美文网首页ElasticSearch实战笔记
14、match all 等查询类型,多条件组合查询和利用fil

14、match all 等查询类型,多条件组合查询和利用fil

作者: 众神开挂 | 来源:发表于2020-03-30 10:39 被阅读0次

    主要内容:match all 等查询类型,多条件组合查询和利用filter进行查询的优化,还简单介绍了排序以及字符串排序

    1、查询类型归纳

    1、match all

    查询所有:

    GET /_search
    {
        "query": {
            "match_all": {}
        }
    }
    
    2、match

    匹配相关field的文本:

    GET /_search
    {
        "query": { "match": { "title": "my elasticsearch article" }}
    }
    
    3、multi match

    将一段搜索的文本使用到多个field上,例如 搜索test_field和test_field1上的匹配test的document

    GET ecommerce/_search
    {
      "query": {
        "multi_match": {
          "query": "fangzhu",
          "fields": ["tags","name"]
        }
      }
    }
    
    4、range query

    可以放在query和filter里面,例子:查询年龄大于35岁的员工

    GET /company/_search 
    {
      "query": {
        "range": {
          "age": {
            "gte": 30
          }
        }
      }
    }
    
    5、term query

    会将搜索词作为整个词到倒排索引中查询

    GET /test_index/_search 
    {
      "query": {
        "term": {
          "title": "xiaomi"
        }
      }
    }
    
    6、terms query

    指定多个term的搜索词:

    title匹配xiaomi或者huawei的document

    GET /test_index/_search 
    {
      "query": {
       "terms": {
         "title": [
           "xiaomi",
           "huawei"
         ]
       }
      }
    }
    

    2、多条件组合查询

    多条件的话,在query下加bool,然后在bool下可以加以下四种条件:
    must,must_not,should,filter

    GET /company/_search
    {
      "query": {
        "bool": {
          "must": [{"match": {"name": "marry"}}],
          "must_not": [{"match": {"address.city": "nanjing"}}],
          "should": [{"match": {"address.province": "jiangsu"}}],
          "filter": {"range": {"join_date": {"lte": "2016-01-01"}}}
        }
      }
    }
    

    每个子查询都会计算一个document针对它的相关度分数,然后bool综合所有分数,合并为一个分数,当然filter是不会计算分数的

    GET /company/_search 
    {
      "query": {
        "constant_score": {
          "filter": {
            "range": {
              "age": {
                "gte": 30
              }
            }
          }
        }
      }
    }
    

    当我们不关心检索词频率TF(Term Frequency)对搜索结果排序的影响时,可以使用constant_score将查询语句query或者过滤语句filter包装起来。

    3、利用filter进行查询的优化

    {
        "query" : {
            "bool" : {
                "must" : [
                {
                    "term" : { "name" : "joe" }
                },
                {
                    "term" : { "year" : 1981 }
                }
                ]
            }
        }
    }
    

    如果用上面命令的格式构建查询,查询对象会将所有的条件绑定到一起存储到缓存中;因此如果我们查询人名相同但是出生年份不同的运动员,ElasticSearch无法重用上面查询命令中的任何信息。因此,我们来试着优化一下查询。由于一千个人可能会有一千个人名,所以人名不太适合缓存起来;但是年份比较适合:

    {
        "query" : {
            "filtered" : {
                "query" : {
                    "term" : { "name" : "joe" }
                },
                "filter" : {
                    "term" : { "year" : 1981 }
                }
            }
        }
    }
    

    我们使用了一个filtered类型的查询对象,查询对象将query元素和filter元素都包含进去了。第一次运行该查询命令后,ElasticSearch就会把filter缓存起来,如果再有查询用到了一样的filter,就会直接用到缓存。就这样,ElasticSearch不必多次加载同样的信息。

    4、快速定位不合法的搜索(validate)

    一般用在那种特别复杂庞大的搜索下,比如你一下子写了上百行的搜索,这个时候可以先用validate api去验证一下,搜索是否合法

    GET /test_index/_validate/query?explain
    {
      "query": {
        "math": {
          "test_field": "test"
        }
      }
    }
    

    5、复习自定义排序

    GET /company/_search 
    {
      "query": {
        "constant_score": {
          "filter": {
            "range": {
              "age": {
                "gte": 30
              }
            }
          }
        }
      },
      "sort": [
        {
          "join_date": {
            "order": "asc"
          }
        }
      ]
    }
    

    6、字符串排序问题

    如果对一个string field进行排序,结果往往不准确,因为分词后是多个单词,再排序就不是我们想要的结果了

    通常解决方案是,将一个string field建立两次索引,一个分词,用来进行搜索;一个不分词,用来进行排序

    创建示例索引

    PUT /website
    {
      "mappings": {
        "properties": {
          "title": {
            "type": "text",
            "fields": {
              "raw": {
                "type": "keyword"
              }
            },
            "fielddata": true
          },
          "content": {
            "type": "text"
          },
          "post_date": {
            "type": "date"
          },
          "author_id": {
            "type": "long"
          }
        }
      }
    }
    

    ​ 插入数据

    PUT website/_doc/1
    {"title":"first article","content":"this is my first article","post_date":"2017-02-01","author_id":110}
    PUT website/_doc/2
    {"title":"second article","content":"this is my second article","post_date":"2017-01-01","author_id":110}
    PUT website/_doc/3
    {"title":"third article","content":"this is my third article","post_date":"2017-03-01","author_id":110}
    

    ​ 开始查询,使用title.raw进行分词,title进行查询

    GET /website/_search
    {
      "query": {
        "match_all": {}
      },
      "sort": [
        {
          "title.raw": {
            "order": "desc"
          }
        }
      ]
    }
    

    参考的文章:

    Elasticsearch查询性能优化 - 简书 https://www.jianshu.com/p/6b5ddb594b1b

    相关拓展:

    为什么Elasticsearch查询变得这么慢了?大数据铭毅天下(公众号同名)-CSDN博客 https://blog.csdn.net/laoyang360/article/details/83048087

    相关文章

      网友评论

        本文标题:14、match all 等查询类型,多条件组合查询和利用fil

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