elasticsearch基础知识

环境

elasticsearch:5.4.3
虚拟机:centos7
kibana:5.4.3
操作系统:win7

概要

本篇属于个人学习笔记奥,不做教程

索引

存储数据到elasticsearch的行为叫做索引

你也许已经注意到 索引 这个词在 Elasticsearch 语境中包含多重意思, 所以有必要做一点儿说明:

索引(名词):

如前所述,一个 索引 类似于传统关系数据库中的一个 数据库 ,是一个存储关系型文档的地方。 索引 (index) 的复数词为 indices 或 indexes 。

索引(动词):

索引一个文档 就是存储一个文档到一个 索引 (名词)中以便它可以被检索和查询到。这非常类似于 SQL 语句中的 INSERT 关键词,除了文档已存在时新文档会替换旧文档情况之外。

倒排索引:

关系型数据库通过增加一个 索引 比如一个 B树(B-tree)索引 到指定的列上,以便提升数据检索速度。Elasticsearch 和 Lucene 使用了一个叫做 倒排索引 的结构来达到相同的目的。

+ 默认的,一个文档中的每一个属性都是 被索引 的(有一个倒排索引)和可搜索的。一个没有倒排索引的属性是不能被搜索到的。我们将在 倒排索引 讨论倒排索引的更多细节。

短语搜索

短语搜索就是精准匹配。

GET megacorp/employee/_search
{
  "query": {
    "match_phrase": {
      "about": "rock climbing"
    }
  }
}

这里就是使用match_phrase过滤器进行精准匹配字段aboutrock climbing的文档。

fielddata

这个fielddata是在官网Mapping章节中。我自己翻译:
译文:

默认情况下,大部分字段都是被索引的(有个倒排索引),以使得他们可以被搜索。
然而,在脚本中排序、聚合和访问字段的值,需要不同的搜索访问模式。

搜索需要回答的问题是“哪些文档包含这些搜索的内容?”,而排序和聚合需要回答的问题是“这个文档中这个字段的值是什么?”

大部分字段都可以使用index-time,磁盘上的doc_values用于这个数据的访问模式;
然而,text字段不支持doc_values

代替的是,text字段使用一个叫做fielddata的数据结构,该数据结构含义是查询时内存数据结构。该数据结构是按需求首次构建在一个被用于聚合、排序和在脚本的字段上。
它是通过读取从磁盘每段的整个倒排索引来构建的,倒排搜索的内容<->文档关系,其存储在jvm堆上的内存上。

text字段默认是没有开启的

fielddata会消耗堆上大量的空间,特别是在加载高基数的text字段时。
一旦fielddata加载到了堆上,它将保持在段的生命周期里。此外,加载fielddata是一个昂贵的过程,它会使得用户遇到延迟命中。这就是为什么默认是禁止的原因。

如果你尝试在text字段上进行排序、聚合和在脚本中访问值,你将看到这个异常:

Fielddata is disabled on text fields by default. Set fielddata=true on [your_field_name] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory.

启用fielddata之前

在你启动fielddata之前,考虑为什么使用text字段用于聚合、排序或在脚本中。这样做通过是没有意义的。

在索引之前应该分析文本字段以便于通过搜索new或者york能够搜索到new york这样的值。当你想要一个名为new york值(桶)时,在这个字段上的聚合操作terms将会返回一个new值(桶:bucket)和york值(桶:bucket)。

说明:bucketelasticsearch执行聚合操作返回的结果值。其实就是数组。
比如我执行:

GET megacorp/employee/_search
{
  "aggs": {
    "all_int": {
      "terms": {"field": "interests"},//terms
      "aggs": {
        "avg_age": {
          "avg": {
            "field": "age"
          }
        }
      }
    }
  }
}

效果如下:

"aggregations": {
    "all_int": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [//buckets
        {
          "key": "music",
          "doc_count": 2,
          "avg_age": {
            "value": 28.5
          }
        },
        {
          "key": "forestry",
          "doc_count": 1,
          "avg_age": {
            "value": 35
          }
        },
        {
          "key": "sports",
          "doc_count": 1,
          "avg_age": {
            "value": 25
          }
        }
      ]
    }
  }

相反,你应该有一个文本字段用于全文搜索,和一个未被分析的关键字字段,其中doc_values启用聚合。如下:

PUT my_index
{
  "mappings": {
    "my_type": {
      "properties": {
        "my_field": { ①
          "type": "text",
          "fields": {
            "keyword": { ②
              "type": "keyword"
            }
          }
        }
      }
    }
  }
}

①:使用my_field字段用于搜索。
②:使用my_field.keyword字段用于聚合、排序和脚本中使用。

text字段上启用fielddata

你可以在已有的text字段使用PUT mapping API启用fielddata,如下所示:

PUT my_index/_mapping/my_type
{
  "properties": {
    "my_field": { ①
      "type":     "text",
      "fielddata": true
    }
  }
}

①:你给my_field指定的映射,应该是由已有的字段映射和fielddata参数组成。

注意:

fielddata.*参数设置必须在同一索引中相同字段名保持一致。
他可以使用PUT mapping API更新已有的值。

在官网教程中开启fielddata方法:

这段代码目的是为了,为了既能搜索,又能聚合目的。

PUT megacorp/_mapping/employee
{
  "properties": {
    "interests":{
      "type": "text",
      "fields": {
        "keyword":{
          "type": "keyword"
        }
      }
    }
  }
}

开启fielddata

PUT megacorp/_mapping/employee
{
  "properties": {
    "interests":{
      "type": "text",
      "fielddata": true
    }
  }
}

PUT和POST区别

这里只是说下小区别:

插入文档时,如果没有指定_id,相应elasticsearch自动生成的话,需要使用post

POST website/blog
{
  "title": "My third blog entry",
  "text": "Third still trying this out...",
  "date": "2017/07/05"
}

结果:

{
  "_index": "website",
  "_type": "blog",
  "_id": "AV0Qv0wO-S86jJ72I7lo",//这个id是自动生成的
  "_version": 1,
  "result": "created",
  "_shards": {
    "total": 2,
    "successful": 2,
    "failed": 0
  },
  "created": true
}

如果使用put,并没有指定_id的话:

PUT website/blog
{
  "title": "My third blog entry",
  "text": "Third still trying this out...",
  "date": "2017/07/05"
}

会报错:

No handler found for uri [/website/blog] and method [PUT]
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

山鬼谣me

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值