美文网首页
二十一、ElasticsSearch中使用terms、range

二十一、ElasticsSearch中使用terms、range

作者: 书写只为分享 | 来源:发表于2019-11-28 00:04 被阅读0次

    1、terms 相当于sql中的in,多值搜索

    GET /forum/article/_search

    {

    "query": {

    "constant_score": {
    
      "filter": {
    
        "bool": {
    
          "must": [
    
            {
    
              "term": {
    
                "tag_cnt": 1
    
              }
    
            },
    
            {
    
              "terms": {
    
                "tag": ["java",”c++”]
    
              }
    
            }
    
          ]
    
        }
    
      }
    
    }
    

    }

    }

    2、搜索浏览量在30~60之间的帖子

    GET /forum/article/_search

    {

    "query": {

    "constant_score": {
    
      "filter": {
    
        "range": {
    
          "view_cnt": {
    
            "gt": 30,
    
            "lt": 60
    
          }
    
        }
    
      }
    
    }
    

    }

    }

    gte lte包含

    3、搜索标题中包含java或elasticsearch的

    GET /forum/article/_search

    {

    "query": {

    "match": {
    
      "title": "java elasticsearch"
    
    }
    

    }

    }

    如果想同时满足,可以加operator

    GET /forum/article/_search

    {

    "query": {

    "match": {
    
      "title": {
    
        "query": "java elasticsearch",
    
        "operator": "and"
    
      }
    
    }
    

    }

    }

    在es内部,会转换成下面的去执行

    {

    "bool": {

    "must": [
    
      { "term": { "title": "java" }},
    
      { "term": { "title": "elasticsearch"   }}
    
    ]
    

    }

    }

    使用minimum_should_match,必须至少匹配其中的多少个关键字,才能作为结果返回,可以用数字也可以使用百分比

    GET /forum/article/_search

    {

    "query": {

    "match": {
    
      "title": {
    
        "query": "java elasticsearch hadoop spark,",
    
        "minimum_should_match": “75”%
    
      }
    
    }
    

    }

    }

    也可以使用下面的should写法,当然,上面的语法,在es内部都会处理成下面的去查询

    GET /forum/article/_search

    {

    "query": {

    "bool": {
    
      "should": [
    
        {"match": {
    
          "title": "java"
    
        }},
    
        {"match": {
    
          "title": "elasticsearch"
    
        }},
    
        {
    
          "match": {
    
            "title": "hadoop"
    
          }
    
        },
    
        {
    
          "match": {
    
            "title": "spark"
    
          }
    
        }
    
      ],
    
    "minimum_should_match":3
    
    }
    

    }

    }

    4、boost的搜索条件权重控制

    指定查询的内容中,什么排在最前面,默认是一样的,数值是你所查询中的条件个数+1,这样才会最优在前

    GET /forum/article/_search

    {

    "query": {

    "bool": {
    
      "should": [
    
        {"match": {
    
          "title": {
    
            "query":"java"
    
          }
    
        }},
    
        {"match": {
    
          "title": {"query":"elasticsearch"}
    
        }},
    
        {
    
          "match": {
    
            "title": {"query":"hadoop"}
    
          }
    
        },
    
        {
    
          "match": {
    
            "title":{"query":"spark",
    
            "boost":5}
    
          }
    
        }
    
      ]
    
    }
    

    }

    }

    5、多shard场景下relevance score不准确问题大揭秘

    如果你的一个index有多个shard的话,可能搜索结果会不准确

    图片1.png

    解决:

    (1)生产环境下,数据量大,尽可能实现均匀分配

    (2)测试环境下,将索引的primary shard设置为1个,number_of_shards=1

    (3)测试环境下,搜索附带search_type=dfs_query_then_fetch参数,会将local IDF取出来计算从新计算,但是生产环境下,不推荐这个参数,因为性能很差。

    GET /forum/article/_search?search_type=dfs_query_then_fetch

    6、dis_max实现best fields策略进行多字段搜索

    (1)****搜索title或content中包含java或solution的帖子
    GET /forum/article/_search
    {
    "query": {
    "bool": {
    "should": [
    {"match": { "title": "java solution"}},
    {"match": {
    "content": "java solution"
    }}
    ]
    }
    }
    }

    {
    "_index": "forum",
    "_type": "article",
    "_id": "4",
    "_score": 0.7120095,
    "_source": {
    "articleID": "QQPX-R-3956-#aD8",
    "userID": 2,
    "hidden": true,
    "postDate": "2017-01-02",
    "tag": [
    "java",
    "elasticsearch"
    ],
    "tag_cnt": 2,
    "view_cnt": 80,
    "title": "this is java, elasticsearch, hadoop blog",
    "content": "elasticsearch and hadoop are all very good solution, i am a beginner"
    }
    },
    {
    "_index": "forum",
    "_type": "article",
    "_id": "5",
    "_score": 0.56008905,
    "_source": {
    "articleID": "DHJK-B-1395-#Ky5",
    "userID": 3,
    "hidden": false,
    "postDate": "2017-03-01",
    "tag": [
    "elasticsearch"
    ],
    "tag_cnt": 1,
    "view_cnt": 10,
    "title": "this is spark blog",
    "content": "spark is best big data solution based on scala ,an programming language similar to java"
    }
    },

    (2)结果分析

    期望的是doc5,结果是doc2,doc4排在了前面

    计算每个document的relevance score:每个query的总分数,乘以matched query数量,除以总query数量

    算一下doc4的分数

    { "match": { "title": "java solution" }},针对doc4,是有一个分数的

    { "match": { "content": "java solution" }},针对doc4,也是有一个分数的

    所以是两个分数加起来,比如说,1.1 + 1.2 = 2.3

    matched query数量 = 2

    总query数量 = 2

    2.3 * 2 / 2 = 2.3

    算一下doc5的分数

    { "match": { "title": "java solution" }},针对doc5,是没有分数的

    { "match": { "content": "java solution" }},针对doc5,是有一个分数的

    所以说,只有一个query是有分数的,比如2.3

    matched query数量 = 1

    总query数量 = 2

    2.3 * 1 / 2 = 1.15

    doc5的分数 = 1.15 < doc4的分数 = 2.3

    (3)best fields策略,dis_max

    best fields策略,就是说,搜索到的结果,应该是某一个field中匹配到了尽可能多的关键词,被排在前面;而不是尽可能多的field匹配到了少数的关键词,排在了前面

    dis_max语法,直接取多个query中,分数最高的那一个query的分数即可

    { "match": { "title": "java solution" }},针对doc4,是有一个分数的,1.1

    { "match": { "content": "java solution" }},针对doc4,也是有一个分数的,1.2

    取最大分数,1.2

    { "match": { "title": "java solution" }},针对doc5,是没有分数的

    { "match": { "content": "java solution" }},针对doc5,是有一个分数的,2.3

    取最大分数,2.3

    然后doc4的分数 = 1.2 < doc5的分数 = 2.3,所以doc5就可以排在更前面的地方,符合我们的需要

    GET /forum/article/_search

    {

    "query": {
    
        "dis_max": {
    
            "queries": [
    
                { "match": { "title": "java solution" }},
    
                { "match": { "content":  "java solution" }}
    
            ]
    
        }
    
    }
    

    }

    (4)、tie_breaker参数优化dis_max搜索效果

    dis_max只取某一个query最大的分数,完全不考虑其他query的分数,可能会导致排序不一对,可以使用tie_breaker将其他query的分数也考虑进去

    GET /forum/article/_search

    {

    "query": {

    "dis_max": {
    
      "queries": [{"match": {
    
        "title": "java solution"
    
      }},{"match": {
    
        "content": "java solution"
    
      }}],"tie_breaker": 0.3
    
    }
    

    }

    }

    7、multi_match语法实现dis_max+tie_breaker

    GET /forum/article/_search

    {

    "query": {

    "multi_match": {
    
      "query": "java solution",
    
      "fields": ["title^2","content"],
    
      "type": "best_fields",
    
      "tie_breaker": 0.3,
    
      "minimum_should_match":"70%"
    
    }
    

    }

    }

    相关文章

      网友评论

          本文标题:二十一、ElasticsSearch中使用terms、range

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