接上一篇继续介绍。
1、查询精确匹配
假设有 { "tags" : ["search"] } { "tags" : ["search", "open_source"] } 两个文档,{ "term" : { "tags" : "search" } }都能匹配,但想只搜索包含一个的值,怎么办? 插入数据时多加一个长度字段: { "tags" : ["search"], "tag_count" : 1 } { "tags" : ["search", "open_source"], "tag_count" : 2 } 查找时加上tag_count精确查找即可。
代码语言:javascript复制GET /_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"tag_count": 1
}
}
},
"term": {
"tags": "search"
}
}
}
2、 忽略多个近义词匹配的相关性
我们知道jump, leap, 和 hop是近义词,它们表示的是同样的概念,因此在匹配时,我们希望匹配jump和leap的文档的相关性不能比仅匹配jump的文档高,该怎么做呢?设置coordination factor (coord)即可。
代码语言:javascript复制GET /_search
{
"query": {
"bool": {
"disable_coord": true,
"should": [
{ "term": { "text": "jump" }},
{ "term": { "text": "hop" }},
{ "term": { "text": "leap" }}
]
}
}
}
3、查询时提高索引的相关性
比如说,我们es存储的是nginx的日志,昨天nginx出问题了,那么查看最近七天的日志时,为了快速找出昨天的错误,也不忽略前天的错误,那么昨天的nginx-log包含error的文档相关性应该比前天的高。默认的boost为1。
代码语言:javascript复制GET /docs_2017_12_*/_search
{
"indices_boost": {
"docs_2017_12_10": 3,
"docs_2017_12_09": 2
},
"query": {
"term": {
"text": "error"
}
}
}
4、更改score计算方法
ES5.0之前默认用的是tf-idf来计算相关性,5.0之后(lucene6)用的BM25来计算相关性。所以这个就不说了。
5、针对数组字符串,match_phrase匹配不准确
代码语言:javascript复制PUT /my_index/groups/1
{
"names": [ "John Abraham", "Lincoln Smith"]
}
GET /my_index/groups/_search
{
"query": {
"match_phrase": {
"names": "Abraham Lincoln"
}
}
}
上述查询可以匹配的到插入的文档。原因是针对names建倒排时,各位置如下:
代码语言:javascript复制Position 1: john
Position 2: abraham
Position 3: lincoln
Position 4: smith
所以查询“Abraham Lincoln”可以查询的到。针对于这种情况通过设置position_increment_gap解决。
代码语言:javascript复制DELETE /my_index/groups/
PUT /my_index/_mapping/groups
{
"properties": {
"names": {
"type": "string",
"position_increment_gap": 100
}
}
}
重新导入数据,建索引时各个位置就会如下所示:
代码语言:javascript复制Position 1: john
Position 2: abraham
Position 103: lincoln
Position 104: smith
这样再次用match_phrase查询时,由于position没有互相挨着,就查询不到“Abraham Lincoln”。
6、Post Filter用于过滤返回的结果集
代码语言:javascript复制PUT /shirts
{
"mappings": {
"item": {
"properties": {
"brand": { "type": "keyword"},
"color": { "type": "keyword"},
"model": { "type": "keyword"}
}
}
}
}
假设我们现在需要找出brand为gucci的所有颜色种类,但是只显示按model聚合的红色的文档,查询语句如下:
代码语言:javascript复制GET /shirts/_search
{
"query": {
"bool": {
"filter": {
"term": { "brand": "gucci" }
}
}
},
"aggs": {
"colors": {
"terms": { "field": "color" }
},
"color_red": {
"filter": {
"term": { "color": "red" }
},
"aggs": {
"models": {
"terms": { "field": "model" }
}
}
}
},
"post_filter": {
"term": { "color": "red" }
}
}