ES 查询优化(二)

作者: YG_9013 | 来源:发表于2017-12-13 21:30 被阅读63次

    接上一篇继续介绍。

    1、查询精确匹配

    假设有
    { "tags" : ["search"] }
    { "tags" : ["search", "open_source"] }
    两个文档,{ "term" : { "tags" : "search" } }都能匹配,但想只搜索包含一个的值,怎么办?
    插入数据时多加一个长度字段:
    { "tags" : ["search"], "tag_count" : 1 }
    { "tags" : ["search", "open_source"], "tag_count" : 2 }
    查找时加上tag_count精确查找即可。

    GET /_search
    {
        "query": {
            "constant_score": {
                "filter": {
                    "term": {
                        "tag_count": 1
                    }
                }
            },
            "term": {
                "tags": "search"
            }
        }
    }
    

    2、 忽略多个近义词匹配的相关性

    我们知道jump, leap, 和 hop是近义词,它们表示的是同样的概念,因此在匹配时,我们希望匹配jump和leap的文档的相关性不能比仅匹配jump的文档高,该怎么做呢?设置coordination factor (coord)即可。

    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。

    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匹配不准确

    PUT /my_index/groups/1
    {
        "names": [ "John Abraham", "Lincoln Smith"]
    }
    
    GET /my_index/groups/_search
    {
        "query": {
            "match_phrase": {
                "names": "Abraham Lincoln"
            }
        }
    }
    

    上述查询可以匹配的到插入的文档。原因是针对names建倒排时,各位置如下:

    Position 1: john
    Position 2: abraham
    Position 3: lincoln
    Position 4: smith
    

    所以查询“Abraham Lincoln”可以查询的到。针对于这种情况通过设置position_increment_gap解决。

    DELETE /my_index/groups/ 
    
    PUT /my_index/_mapping/groups 
    {
        "properties": {
            "names": {
                "type":                "string",
                "position_increment_gap": 100
            }
        }
    }
    

    重新导入数据,建索引时各个位置就会如下所示:

    Position 1: john
    Position 2: abraham
    Position 103: lincoln
    Position 104: smith
    

    这样再次用match_phrase查询时,由于position没有互相挨着,就查询不到“Abraham Lincoln”。

    6、Post Filter用于过滤返回的结果集

    PUT /shirts
    {
        "mappings": {
            "item": {
                "properties": {
                    "brand": { "type": "keyword"},
                    "color": { "type": "keyword"},
                    "model": { "type": "keyword"}
                }
            }
        }
    }
    

    假设我们现在需要找出brand为gucci的所有颜色种类,但是只显示按model聚合的红色的文档,查询语句如下:

    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" }
      }
    }
    

    相关文章

      网友评论

        本文标题:ES 查询优化(二)

        本文链接:https://www.haomeiwen.com/subject/yjzzixtx.html