zoukankan      html  css  js  c++  java
  • 第2部分 Elasticsearch查询-请求体查询、排序

    一、请求体查询

    请求体 search API, 之所以称之为请求体查询(Full-Body Search),因为大部分参数是通过http请求体而非查询字符串来传递的。
    请求体查询:不仅可以处理自身的查询请求,还允许你对结果进行片段强调(高亮)、对所有或部分结果进行聚合分析,同时还可以给出 你是不是想找 的建议,这些建议可以引导使用者快速找到他想要的结果。
    某些特定语言(特别是 JavaScript)的 HTTP 库是不允许 GET 请求带有请求体的,可以用POST代替。

    1、空查询

    空查询,空的请求体会返回所有索引中的所有文档

    GET /_search
    {}
    

    用一个查询字符串,在多个索引库中和多个types中查询:

    GET /index_2014*/type1,type2/_search
    {}
    

    使用 from 和 size 参数分页:

    GET /_search
    {
      "from": 30,
      "size": 10
    }
    

    2、查询表达式(Query DSL)

    使用

    将查询语句传递给query参数

    GET /_search
    {
        "query": YOUR_QUERY_HERE
    }
    

    查询语句结构

    典型结构:

    {
        QUERY_NAME: {
            ARGUMENT: VALUE,
            ARGUMENT: VALUE,...
        }
    }
    

    针对某个字段:

    {
        QUERY_NAME: {
            FIELD_NAME: {
                ARGUMENT: VALUE,
                ARGUMENT: VALUE,...
            }
        }
    }
    

    例子:

    GET /_search
    {
        "query": {
            "match": {
                "city": "Shaft"
            }
        }
    }
    

    match_all查询

    空查询(empty search),在功能上等价于使用 match_all 查询:

    GET /_search
    {
        "query": {
            "match_all": {}
        }
    }
    

    合并查询语句

    叶子语句:用于将查询字符串和一个字段(或者多个字段)对比,match
    复合语句:主要用于合并其它查询语句,bool

    GET /_search
    {
        "query": {
            "bool": {
                "must":{"match":{"state":"KY"}},
                "must_not":{"match":{"city:":"Yettem"}},
                "should":{"match":{"address":"382 Columbia Street"}},
                "filter":   { "range": { "age" : { "gt" : 30 }} }
              }
        }
    }
    

    3、查询与过滤

    过滤
    查询被设置成一个“不评分”或者“过滤”查询。匹配或者不匹配。
    查询
    查询就变成了一个“评分”的查询。一个评分查询计算每一个文档与此查询的相关程度,同时将这个相关程度分配给表示相关性的字段_score,并且按照相关性对匹配到的文档进行排序。
    注意
    "filter" 这个词表示不评分、只过滤情况下的查询。== "filter" 、 "filtering query" 和 "non-scoring query"
    "query" 我们指的是 "scoring query"
    性能差异
    过滤查询(Filtering queries:计算快,经常用不评分查询结果稀少,结果会被缓存到内存中以便快速读取,所以有各种各样的手段来优化查询结果。
    评分查询(scoring queries):计算费力,查询结果并不缓存。

    4、最重要的查询

    match_all查询

    匹配所有文档,默认查询方式。它经常与 filter 结合使用

    { "match_all": {}}
    

    match查询

    标准查询,无论你在任何字段上进行的是全文搜索还是精确查询。
    全文字段使用时,在执行查询前,它将用正确的分析器去分析查询字符串

    { "match": { "tweet": "About Search" }}
    

    在一个精确值字段使用,例如数字、日期、布尔或者一个 not_analyzed 字符串字段,它会精确匹配给定的值:

    { "match": { "age":    26           }}
    { "match": { "date":   "2014-09-01" }}
    { "match": { "public": true         }}
    { "match": { "tag":    "full_text"  }}
    

    multi_match 查询

    可以在多个字段上执行相同的 match 查询:

    GET /_search
    {
        "query": {
            "multi_match": {
               "query":    "728",
               "fields":   [ "address", "account_number" ]
             }
        }
    }
    

    解释:查询在address和account_number字段带有728字符串的文档。

    range查询

    找出那些落在指定区间内的数字或者时间:

    {
        "range": {
            "age": {
                "gte":  20,
                "lt":   30
            }
        }
    }
    

    操作符如下:

    • gt 大于
    • gte 大于等于
    • lt 小于
    • lte 小于等于

    term查询

    被用于精确值匹配,这些精确值可能是数字、时间、布尔或者那些 not_analyzed 的字符串:

    { "term": { "age":    26           }}
    { "term": { "date":   "2014-09-01" }}
    { "term": { "public": true         }}
    { "term": { "tag":    "full_text"  }}
    

    注意:以上某一行

    terms查询

    terms 查询和 term 查询一样,但它允许你指定多值进行匹配。如果这个字段包含了指定值中的任何一个值,那么这个文档满足条件:

    GET /_search
    {
        "query": {
            "terms": { "age": [39,38,30 ] }
        }
    }
    

    解释:年龄为39或38或30的文档。

    exists查询、missing查询

    用于查找那些指定字段中有值 (exists) 或无值 (missing) 的文档:

    GET /_search
    {
        "query": {
            "exists": {
                "field":    "title"
            }
        }
    }
    

    解释:查询title字段有值的文档

    5、组合多查询

    可用bool查询,它接受以下参数:

    • must:文档 必须 匹配这些条件才能被包含进来。
    • must_not:文档 必须不 匹配这些条件才能被包含进来。
    • should:如果满足这些语句中的任意语句,将增加_score ,否则,无任何影响。它们主要用于修正每个文档的相关性得分。
    • filter:必须 匹配,但它以不评分、过滤模式来进行。这些语句对评分没有贡献,只是根据过滤标准来排除或包含文档。

    bool查询

    查找 title 字段匹配 how to make millions 并且不被标识为 spam 的文档。那些被标识为 starred 或在2014之后的文档,将比另外那些文档拥有更高的排名。如果_两者_都满足,那么它排名将更高:

    {
        "bool": {
            "must":     { "match": { "title": "how to make millions" }},
            "must_not": { "match": { "tag":   "spam" }},
            "should": [
                { "match": { "tag": "starred" }},
                { "range": { "date": { "gte": "2014-01-01" }}}
            ]
        }
    }
    

    增加带过滤器的bool查询

    如果我们不想因为文档的时间而影响得分,可以用 filter 语句来重写前面的例子:

    {
        "bool": {
            "must":     { "match": { "title": "how to make millions" }},
            "must_not": { "match": { "tag":   "spam" }},
            "should": [
                { "match": { "tag": "starred" }}
            ],
            "filter": {
              "range": { "date": { "gte": "2014-01-01" }} ![0f67842b8cc059137a88288e95115a18.png](evernotecid://20C3AB82-3EA7-481C-B3D2-078868D90727/appyinxiangcom/23631184/ENNote/p10?hash=0f67842b8cc059137a88288e95115a18)
              
            }
        }
    }
    

    如果你需要通过多个不同的标准来过滤你的文档,bool查询本身也可以被用做不评分的查询,简单地将它放置到filter语句中并在内部构建布尔逻辑:

    {
        "bool": {
            "must":     { "match": { "title": "how to make millions" }},
            "must_not": { "match": { "tag":   "spam" }},
            "should": [
                { "match": { "tag": "starred" }}
            ],
            "filter": {
              "bool": { ![0f67842b8cc059137a88288e95115a18.png](evernotecid://20C3AB82-3EA7-481C-B3D2-078868D90727/appyinxiangcom/23631184/ENNote/p10?hash=0f67842b8cc059137a88288e95115a18)
              
                  "must": [
                      { "range": { "date": { "gte": "2014-01-01" }}},
                      { "range": { "price": { "lte": 29.99 }}}
                  ],
                  "must_not": [
                      { "term": { "category": "ebooks" }}
                  ]
              }
            }
        }
    }
    
    

    constant_score查询

    可以使用它来取代只有 filter 语句的 bool 查询,性能相同,但是简洁:

    {
        "constant_score":   {
            "filter": {
                "term": { "category": "ebooks" } ![0f67842b8cc059137a88288e95115a18.png](evernotecid://20C3AB82-3EA7-481C-B3D2-078868D90727/appyinxiangcom/23631184/ENNote/p10?hash=0f67842b8cc059137a88288e95115a18)
                
            }
        }
    }
    

    解释:term 查询被放置在 constant_score 中,转成不评分的 filter。这种方式可以用来取代只有 filter 语句的 bool 查询。

    6、验证查询

    validate-query API 可以用来验证查询是否合法:

    GET /bank/address/_validate/query?
    {
       "query": {
          "address" : {
             "match" : "Avenue"
          }
       }
    }
    

    解释不合法原因:

    GET /bank/address/_validate/query?explain
    {
       "query": {
          "address" : {
             "match" : "Avenue"
          }
       }
    }
    

    二、排序与相关性

    1、排序

    在 Elasticsearch 中, 相关性得分 由一个浮点数进行表示,并在搜索结果中通过_score 参数返回, 默认排序是_score 降序。

    使用 constant_score 查询进行替代bool,让所有文档应用一个恒定分数(默认为 1 ),不是0:

    GET /_search
    {
        "query" : {
            "constant_score" : {
                "filter" : {
                    "term" : {
                        "user_id" : 1
                    }
                }
            }
        }
    }
    

    2、按照字段的值排序

    GET /_search
    {
        "query" : {
            "bool" : {
                "filter" : { "term" : { "age" : 40 }}
            }
        },
        "sort": { "balance": { "order": "desc" }}
    }
    

    3、多级排序

    假定我们想要结合使用 date和_score 进行查询,并且匹配的结果首先按照日期排序,然后按照相关性排序:

    GET /_search
    {
        "query" : {
            "bool" : {
                "must":   { "match": { "tweet": "manage text search" }},
                "filter" : { "term" : { "user_id" : 2 }}
            }
        },
        "sort": [
            { "date":   { "order": "desc" }},
            { "_score": { "order": "desc" }}
        ]
    }
    

    Query-string 搜索 也支持自定义排序,可以在查询字符串中使用 sort 参数:

    GET /_search?sort=date:desc&sort=_score&q=search
    

    4、多值字段排序

    情形:一个字段里有多个值,并且这些值没有顺序,应该选择哪个值排序。
    对于数字或日期,你可以将多值字段减为单值,这可以通过使用 min 、 max 、 avg 或是 sum 排序模式 。 例如你可以按照每个 date 字段中的最早日期进行排序,通过以下方法:

    "sort": {
        "dates": {
            "order": "asc",
            "mode":  "min"
        }
    }
    

    5、字符串排序与多字段

    一个简单的方法是用两种方式对同一个字符串进行索引,这将在文档中包括两个字段: analyzed 用于搜索, not_analyzed 用于排序。

    为一个多字段映射如:

    "tweet": { ![0f67842b8cc059137a88288e95115a18.png](evernotecid://20C3AB82-3EA7-481C-B3D2-078868D90727/appyinxiangcom/23631184/ENNote/p10?hash=0f67842b8cc059137a88288e95115a18)
    
        "type":     "string",
        "analyzer": "english",
        "fields": {
            "raw": {        
                "type":  "string",
                "index": "not_analyzed"
            }
        }
    }
    
    
    • tweet 主字段与之前的一样: 是一个 analyzed 全文字段。
    • 新的 tweet.raw 子字段是 not_analyzed.

    现在,使用 tweet 字段用于搜索,tweet.raw 字段用于排序:

    GET /_search
    {
        "query": {
            "match": {
                "tweet": "elasticsearch"
            }
        },
        "sort": "tweet.raw"
    }
    

    注意:以全文 analyzed 字段排序会消耗大量的内存

  • 相关阅读:
    linux运维、架构之路-MySQL备份与恢复(四)
    linux运维、架构之路-MHA高可用方案
    Tensorflow环境安装
    Sublime Text3 旧版本下载以及破解激活方式
    《SDN期末作业——实现负载均衡》
    SDN第六次上机作业
    自定义Toast的出现样式
    SDN第五次上机作业
    SDN第4次上机作业
    Context与ApplicationContext的区别
  • 原文地址:https://www.cnblogs.com/yangjianan/p/10525925.html
Copyright © 2011-2022 走看看