Elasticsearch基础知识汇总

555 阅读8分钟
  • 背景
  • 为什么出现这项技术
  • 行业其它类似技术的状况
  • 自身特点
  • 能够做什么

1、怎么用

1.1 分片扩展

主分片的数量在创建索引时已经确定,实际上,这个数量定义了能存储到索引里数据的最大 数量( 实际的数量取决于你的数据、 硬件和应用场景),然而, 主分片或者复制分片都可以 处理读请求——搜索或文档检索, 所以数据的冗余越多, 我们能处理的搜索吞吐量就越大。 复制分片的数量可以在运行中的集群中动态地变更, 这允许我们可以根据需求扩大或者缩小 规模。 让我们把复制分片的数量从原来的 1 增加到 2 :

PUT /blogs/_settings  
{
    "number_of_replicas" : 2
}

当然,在同样数量的节点上增加更多的复制分片并不能提高性能,因为这样做的话平均每个分片的所占有的硬件资源就减少了(注:大部分请求都聚集到了分片少的节点,导致一个节点吞吐量太大,反而降低性能),你需要增加硬件来提高吞吐量。
不过这些额外的复制节点使我们有更多的冗余:通过以上对节点的设置,我们能够承受两个节点故障而不丢失数据。

1.2 索引的属性详解

_source、_all、store和index属性

现在有一份原始文档,内容如下:

{
    "title":"我是中国人""content":"热爱祖国"
}

_source

    把数据写入到ES中,默认情况下,Elasticsearch里面有2份内容,一份是原始文档,也就是_source字段里的内容。另一份是倒排索引,倒排索引中的数据结构是倒排记录表,记录了词项和文档之间的对应关系,比如关键词”中国人”包含在文档ID为1的文档中,倒排记录表中存储的就是这种对应关系,当然也包括词频等更多信息。

index

    那么文档索引到Elasticsearch的时候,默认情况下是对所有字段创建倒排索引的(动态mapping解析出来为数字类型、布尔类型的字段除外),某个字段是否生成倒排索引是由字段的index属性控制的,在Elasticsearch 5之前,index属性的取值有三个:

  1. analyzed:
    字段被索引,会做分词,可搜索。反过来,如果需要根据某个字段进搜索,index属性就应该设置为analyzed。
  2. not_analyzed:
    字段值不分词,会被原样写入索引。反过来,如果某些字段需要完全匹配,比如人名、地名,index属性设置为not_analyzed为佳。
  3. no:
    字段不写入索引,当然也就不能搜索。反过来,有些业务要求某些字段不能被搜索,那么index属性设置为no即可。

_all

    _all字段包含了一个文档里面的所有信息,是一个超级字段。以上面文档为例,如果开启_all字段,那么title+content会组成一个超级字段,这个字段包含了其他字段的所有内容,当然也可以设置只存储某几个字段到_all属性里面或者排除某些字段。

store

做一个说明:
    用户查询时输入“中国人”,这时还没分词进行查询时,“中国人”称为query,然后ES从倒排索引列表中查找哪些文档包含了的“中国人”,,注意变化,分词之前" 中国人"是用户查询(query),分词之后在倒排索引中"中国人"是词项(term)。Elasticsearch根据文档ID(通常是文档ID的集合)返回文档内容给用户。

    根据结果高亮的场景来分析理解store属性,高亮实质上是根据倒排记录中的词项偏移位置,找到关键词,加上前端的高亮代码。这里就要说到store属性,store属性用于指定是否将原始字段写入索引,默认取值为no。如果在Lucene中,高亮功能和store属性是否存储息息相关,因为需要根据偏移位置到原始文档中找到关键字才能加上高亮的片段。在Elasticsearch,因为_source中已经存储了一份原始文档,可以根据_source中的原始文档实现高亮,在索引中再存储原始文档就多余了,所以Elasticsearch默认是把store属性设置为no。

    注意:如果想要对某个字段实现高亮功能,_source和store至少保留一个。下面会给出测试代码。

1.3 API使用

1.3.1 常用API总结

1.3.1.1 集群状态方面

  • _cat命令 GET /_cat

  • 如何安全重启索引

    第一步:先暂停集群的shard自动均衡。

    curl -XPUT http://192.168.1.2:9200/_cluster/settings -d'
    {
        "transient" : {
            "cluster.routing.allocation.enable" : "none"
        }
    }'
    

    第二步:shutdown你要升级的节点

    curl -XPOST http://192.168.1.3:9200/_cluster/nodes/_local/_shutdown
    

    第三步:升级重启该节点,并确认该节点重新加入到了集群中

    第四步:重复2-3步,升级重启其它要升级的节点。

    第五步:重启启动集群的shard均衡

    curl -XPUT http://192.168.1.2/_cluster/settings -d'
    {
        "transient" : {
            "cluster.routing.allocation.enable" : "all"
        }
    }'
    

    到此整个集群安全升级并且重启结束。

1.3.1.2 index设置方面

1、settings

  • 使用 curl设置举例
curl -XPUT http://192.168.12.165:9200/testindex -H "Content-Type:application/json" -d'
"settings" : {
        "number_of_shards" : "3",
        "number_of_replicas" : "0"
    }
'

2、mapping

3、开启和关闭index

  • 使用head插件关闭与开启某个index
    状态说明:在close时,该索引所占用的相关内存,(包括各种query cache,前缀索引等等)都会被释放,然后该索引达到不可查的状态,open时会前缀索引再重新加载到内存

  • 调用api

1.3.1.3 数据分析方面

  1. analyzer测试

测试分词器分词后的效果,使用中文分词器ik的ik_smart模式分词下面的句子

GET /_analyze
{
   "text" : "this二个人为什么OKOK",
  "analyzer":"ik_smart"
}

结果:

{
  "tokens" : [
    {
      "token" : "二个人",
      "start_offset" : 4,
      "end_offset" : 7,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "为什么",
      "start_offset" : 7,
      "end_offset" : 10,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "okok",
      "start_offset" : 10,
      "end_offset" : 14,
      "type" : "ENGLISH",
      "position" : 2
    }
  ]
}

1.3.1.4 数据的增删改查方面

  1. term和match的区别
    term是代表完全匹配,即不进行分词器分析,文档中必须包含整个搜索的词汇
    match和term的区别是,match查询的时候,elasticsearch会根据你给定的字段提供合适的分析器,而term查询不会有分析器分析的过程,match查询相当于模糊匹配,只包含其中一部分关键词就行

  2. 车牌号模糊与时间范围检索举例

GET /multobj/x_model/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "plateNumber": "京BA"
          }
        },
        {
          "range": {
            "ctime": {
              "lt": "2019-10-31T01:00:00",
              "gte": "2019-10-31T00:00:00"
            }
          }
        }
      ]
    }
  },
  "size": 1000,
  "sort": {
    "ctime": "asc"
  },
  "_source": [
    "plateNumber",
    "brand",
    "ctime"
  ]
}
  1. 多属性查询
#多属性查询
GET multobj004/_doc/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "range": {
            "ctime": {
              "gte": "2019-01-01T00:00:00",
              "lt": "2020-01-01T00:00:00"
            }
          }
        },
        {
          "match": {
            "targetType": "car"
          }
        },
        {
          "match": {
            "sourceType": "zipFile"
          }
        },
        {
          "match": {
            "color": "white"
          }
        },
        {
          "match": {
            "plateNumber": {
              "query": "23",
              "analyzer": "whitespace"
            }
          }
        }
      ]
    }
  },
  "_source": [
    "plateNumber",
    "UUID",
    "ctime",
    "targetType",
    "sourceType"
  ],
  "from": 0,
  "size": 1000,
  "sort": {
    "ctime": "desc"
  }
}

查询接口返回结果字段说明

took— Elasticsearch执行搜索的时间(以毫秒为单位)  
timed_out — 告诉我们搜索是否超时  
_shards — 告诉我们搜索了多少个碎片,以及搜索成功/失败碎片的计数  
hits — 搜索结果  
hits.total — 符合我们搜索条件的文档总数  
hits.hits — 实际的搜索结果数组(默认为前10个文档)  
hits.sort — 对结果进行排序(如果按分数排序则丢失)  
hits._score和max_score — 暂时忽略这些字段
  1. 提高精度(Improving Precision)
    match查询接受一个operator参数,该参数的默认值是"or"。你可以将它改变为"and"来要求所有的词条都需要被匹配:
GET /my_index/my_type/_search  
{  
    "query": {  
        "match": {  
            "title": {      
                "query":    "BROWN DOG!",  
                "operator": "and"  
            }  
        }  
    }  
} 
  1. 控制精度(Controlling Precision)

在all和any中选择有种非黑即白的感觉。如果用户指定了5个查询词条,而一份文档只包含了其中的4个呢?将"operator"设置成"and"会将它排除在外。有时候这正是你想要的,但是对于大多数全文搜索的使用场景,你会希望将相关度高的文档包含在结果中,将相关度低的排除在外。换言之,我们需要一种介于两者中间的方案。
match查询支持minimum_should_match参数,它能够让你指定有多少词条必须被匹配才会让该文档被当做一个相关的文档。尽管你能够指定一个词条的绝对数量,但是通常指定一个百分比会更有意义,因为你无法控制用户会输入多少个词条:

GET /my_index/my_type/_search
{
  "query": {
    "match": {
      "title": {
        "query": "quick brown dog",
        "minimum_should_match": "75%"
      }
    }
  }
}  

当以百分比的形式指定时,minimum_should_match会完成剩下的工作:在上面拥有3个词条的例子中,75%会被向下舍入到66.6%,即3个词条中的2个。无论你输入的是什么,至少有2个词条被匹配时,该文档才会被算作最终结果中的一员。

minimum_should_match参数非常灵活,根据用户输入的词条的数量,可以适用不同的规则。具体可以参考minimum_should_match参数的相关文档。

分页、聚合、统计、通配等 blog.csdn.net/majun_guang…
Elasticsearch 参考指南(执行器、聚合) segmentfault.com/a/119000001…

1.3 单个index不支持多个type

参考资料
Elasticsearch学习,请先看这一篇 cloud.tencent.com/developer/a…