使用query关键字进行检索,倾向于相关度搜索,故需要计算评分。搜索是Elasticsearch最关键和重要的部分
示例代码
#查询全部数据 如果不添加size参数则默认为10 GET test_dynamic_mapping/_search { "query": { "match_all": {} }, "size": 20 } 或者 GET test_dynamic_mapping/_search
概念:相关度评分用于对搜索结果排序,评分越高则认为其结果和搜索的预期值相关度越高,即越符合搜索预期值。在7.x之前相关度评分默认使用TF/IDF算法计算而来,7.x之后默认为BM25。在核心知识篇不必关心相关评分的具体原理,只需知晓其概念即可。
排序:相关度评分为搜索结果的排序依据,默认情况下评分越高,则结果越靠前。
禁用_source:
好处:节省存储开销
坏处:
不支持update、update_by_query和reindex API。
不支持高亮。
不支持reindex、更改mapping分析器和版本升级。
通过查看索引时使用的原始文档来调试查询或聚合的功能。
将来有可能自动修复索引损坏。
总结:如果只是为了节省磁盘,可以压缩索引比禁用_source更好。
数据源过滤器:
Including:结果中返回哪些field
Excluding:结果中不要返回哪些field,不返回的field不代表不能通过该字段进行检索,因为元数据不存在不代表索引不存在
在mapping中定义过滤:支持通配符,但是这种方式不推荐,因为mapping不可变
PUT product { "mappings": { "_source": { "includes": [ "name", "price" ], "excludes": [ "desc", "tags" ] } } }
常用过滤规则
"_source": "false",
"_source": "obj.*",
"_source": [ "obj1.*", "obj2.*" ],
"_source": { "includes": [ "obj1.*", "obj2.*" ], "excludes": [ "*.description" ] }
GET /product/_search
GET /product/_search?q=name:xiaomi
GET /product/_search?from=0&size=2&sort=price:asc
GET /product/_search?q=date:2021-06-01
GET /product/search?q=2021-06-01
all搜索相当于在所有有索引的字段中检索
all搜索示例代码:
# 验证_all搜索 PUT product { "mappings": { "properties": { "desc": { "type": "text", "index": false } } } } # 先初始化数据 POST /product/_update/5 { "doc": { "desc": "erji zhong de kendeji 2021-06-01" } }
GET index/_search { "query": { *** } }
匹配包含某个term的子句
匹配所有结果的子句
多字段条件
短语查询
匹配和搜索词项完全相同的结果
GET product/_search { "query": { "term": { "name": "xiaomi phone" } } }
match_phrase 会将检索关键词分词, match_phrase的分词结果必须在被检索字段的分词中都包含,而且顺序必须相同,而且默认必须都是连续的
term搜索不会将搜索词分词
GET product/_search { "query": { "match_phrase": { "name": "xiaomi phone" } } }
term是对于搜索词不分词, keyword是字段类型,是对于source data中的字段值不分词
GET product/_search { "query": { "term": { "name": "xiaomi phone" } } } GET product/_search { "query": { "term": { "name.keyword": "xiaomi phone" } } }
匹配和搜索词项列表中任意项匹配的结果
GET product/_search { "query": { "terms": { "tags": [ "lowbee", "gongjiaoka" ], "boost": 1.0 } } }
范围查找
GET /_search { "query": { "range": { "age": { "gte": 10, "lte": 20, "boost": 2.0 } } } }
GET product/_search { "query": { "range": { "date": { "gte": "2021-04-15", "lt": "2021-04-16" } } } } GET product/_search { "query": { "range": { "date": { "gte": "now-1d/d", "lt": "now/d" } } } } GET product/_search { "query": { "range": { "date": { "time_zone": "+08:00", "gte": "2021-04-15T08:00:00", "lt": "now" } } } }
GET _search { "query": { "constant_score": { "filter": { "term": { "status": "active" } } } } } GET product/_search { "query": { "bool": { "filter": { "term": { "name": "phone" } } } } }
query和filter的主要区别在于: filter是结果导向的而query是过程导向。query倾向于“当前文档和查询的语句的相关度”而filter倾向于“当前文档和查询的条件是不是相符”。即在查询过程中,query是要对查询的每个结果计算相关性得分的,而filter不会。另外filter有相应的缓存机制,可以提高查询效率。
可以组合多个查询条件,bool查询也是采用more_matches_is_better的机制,因此满足must和should子句的文档将会合并起来计算分值
GET product/_search { "query": { "bool": { "must": [ {} ], "must_not": [ {} ], "should": [ {} ], ...... } } }
必须满足子句(查询)必须出现在匹配的文档中,并将有助于得分
GET product/_search { "query": { "bool": { "must": [ { "match": { "name": "xiaomi phone" } }, { "match_phrase": { "desc": "shouji zhong" } } ] } } }
过滤器 不计算相关度分数,cache☆子句(查询)必须出现在匹配的文档中。但是不像 must查询的分数将被忽略。Filter子句在filter上下文中执行,这意味着计分被忽略,并且子句被考虑用于缓存。
#filter 不计算相关度得分 GET product/_search { "query": { "bool": { "filter": [ { "match": { "name": "xiaomi phone" } }, { "match_phrase": { "desc": "shouji zhong" } } ] } } }
可能满足 or子句(查询)应出现在匹配的文档中。
GET product/_search { "query": { "bool": { "should": [ { "match_phrase": { "name": "xiaomi nfc" } }, { "range": { "price": { "lte": "500" } } } ] } } }
必须不满足 不计算相关度分数 not子句(查询)不得出现在匹配的文档中。子句在过滤器上下文中执行,这意味着计分被忽略,并且子句被视为用于缓存。由于忽略计分,0因此将返回所有文档的分数。
#must not 不计算相关度得分 #条件1: 排除包含xiaomi的和包含nfc的(不能包含xiaomi和nfc中的任意一个) #条件2: 排除价格大于等于500的 GET product/_search { "query": { "bool": { "must_not": [ { "match": { "name": "xiaomi nfc" } }, { "range": { "price": { "gte": "500" } } } ] } } }
参数指定should返回的文档必须匹配的子句的数量或百分比。如果bool查询包含至少一个should子句,而没有must或 filter子句,则默认值为1。否则,默认值为0
#(must或者filter)和should组合 #条件1:价格小于10000 #条件2:name中包含"hongmi"或者"xiaomi nfc phone" GET product/_search { "_source": false, "query": { "bool": { "filter": [ { "range": { "price": { "lte": "10000" } } } ], "should": [ { "match_phrase": { "name": "nfc phone" } }, { "match": { "name": "erji" } }, { "bool": { "must": [ { "range": { "price": { "gte": 900, "lte": 3000 } } } ] } } ], "minimum_should_match": 2 } } }