搜索是ES最最核心的内容,没有之一。前面章节的内容,索引、动态映射、分词器等都是铺垫,最重要的就是最后点击搜索这一下。下面我们就看看点击搜索这一下的背后,都做了哪些事情。
分数(score)ES的搜索结果是按照相关分数的高低进行排序的,咦?! 怎么没说搜索先说搜索结果的排序了?咱们这里先把这个概念提出来,因为在搜索的过程中,会计算这个分数。这个分数代表了这条记录匹配搜索内容的相关程度。分数是一个浮点型的数字,对应的是搜索结果中的_score字段,分数越高代表匹配度越高,排序越靠前。
在ES的搜索当中,分为两种,一种计算分数,而另外一种是不计算分数的。
查询(query context)查询,代表的是这条记录与搜索内容匹配的怎么样,除了决定这条记录是否匹配外,还要计算这条记录的相关分数。这个和咱们平时的查询是一样的,比如我们搜索一个关键词,分词以后匹配到相关的记录,这些相关的记录都是查询的结果,那这些结果谁排名靠前,谁排名靠后呢?这个就要看匹配的程度,也就是计算的分数。
过滤(filter context)过滤,代表的含义非常的简单,就是YES or NO,这条记录是否匹配查询条件,它不会计算分数。频繁使用的过滤还会被ES加入到缓存,以提升ES的性能。下面我们看一个查询和过滤的例子,这个也是ES官网中的例子。
GET /_search { "query": { "bool": { "must": [ { "match": { "title": "Search" }}, { "match": { "content": "Elasticsearch" }} ], "filter": [ { "term": { "status": "published" }}, { "range": { "publish_date": { "gte": "2015-01-01" }}} ] } } }我们看一下请求的路径/_search,这个是请求的路径,而请求的方法是GET,我们再看请求体中,有一个query,这个代表着查询的条件。而bool中的must被用作query context,它在查询的时候会计算记录匹配的相关分数。filter中的条件用作过滤,只会把符合条件的记录检索出来,不会计算分数。
组合查询组合查询包含了其他的查询,像我们前面提到的query context和filter context。在组合查询中,分为很多种类型,我们挑重点的类型给大家介绍一下。
Boolean Queryboolean查询,前面我们写的查询语句就是一个boolean查询,boolean查询中有几个关键词,表格如下:
关键词 描述must 必须满足的条件,而且会计算分数,
filter 必须满足的条件,不会计算分数
should 可以满足的条件,会计算分数
must_not 必须不满足的条件,不会计算分数
我们看看下面的查询语句:
POST _search { "query": { "bool" : { "must" : { "term" : { "user" : "kimchy" } }, "filter": { "term" : { "tag" : "tech" } }, "must_not" : { "range" : { "age" : { "gte" : 10, "lte" : 20 } } }, "should" : [ { "term" : { "tag" : "wow" } }, { "term" : { "tag" : "elasticsearch" } } ], "minimum_should_match" : 1, "boost" : 1.0 } } }上面的查询是一个典型的boolean组合查询,里边的关键词都用上了。很多小伙伴们可能对must和should的区别不是很了解,must是必须满足的条件,我们的例子中must里只写了一个条件,如果是多个条件,那么里边的所有条件必须满足。而should就不一样了,should里边现在列出了两个条件,并不是说这两个条件必须满足,到底需要满足几个呢?我们看一下下面的关键字minimum_should_match,从字面上我们就可以看出它的含义,最小should匹配数,在这里设置的是1,也就是说,should里的条件只要满足1个,就算匹配成功。在boolean查询中,如果存在一个should条件,而没有filter和must条件的话,那么minimum_should_match的默认值是1,其他情况默认值是0。
我们再看一个实际的例子吧,还记得前面我们创建的ik_index索引吗?索引中存在着几条数据,数据如下:
_index _type _id ▲_score id title descik_index _doc fEsN-HEBZl0Dh1ayKWZb 1 1 苹果 苹果真好吃
ik_index _doc 2 1 1 香蕉 香蕉真好吃
ik_index _doc 1 1 1 香蕉 香蕉真好吃
ik_index _doc 3 1 1 橘子 橘子真好吃
ik_index _doc 4 1 1 桃子 桃子真好吃