zoukankan      html  css  js  c++  java
  • ElasticSearch查询 第三篇:词条查询

    《ElasticSearch查询》目录导航:

    字符串的完全匹配是指字符的大小写,字符的数量和位置都是相同的,词条(term)查询使用字符的完全匹配方式进行文本搜索,词条查询不会分析(analyze)查询字符串,给定的字段必须完全匹配词条查询中指定的字符串。由于词条查询的字符串是未经分析(analyzed)的词条,因此,词条查询经常用于结构化的数据,例如,数值,日期等,当用于文本搜索时,最好在索引映射中设置字符串字段不被索引,也就是说,设置index属性为not_analyzed,否则,只能对该字段进行单词条搜索,也可以使用多字段(fields)属性,定义一个不被分析的字段,原始字段用于全文搜索,而多字段用于词条搜索:

    "properties":
    {  
        "title":{  "type":"string","index":"analyzed"
                   "fields":{ "title_exact":{"type":"string","index":"not_analyzed"} }
        },

    一,词条查询和全文查询

    词条(term)查询和全文(fulltext)查询最大的不同之处是:全文查询首先分析(Analyze)查询字符串,使用默认的分析器分解成一系列的分词,term1,term2,termN,然后从索引中搜索是否有文档包含这些分词中的一个或多个,如果执行的match查询,默认的操作符(operator)是,只要文档的字段值能够匹配任意一个词条,该文档就匹配查询条件;而词条查询是字符的完全匹配,只有当字段的字符完全匹配查询字符串时,ElasticSearch引擎才判定文档匹配查询条件:

    词条查询:词条查询不会分析查询条件,只有当词条和查询字符串完全匹配时,才匹配搜索。当在未被分析的字段中进行搜索时,和查询字符串完全匹配的文档会被返回;如果在已分析(Analyzed)的字段中进行搜索,词条必须是小写的单个词条,否则,匹配不到任何文档;

    全文查询:ElasticSearch引擎会先分析(analyze)查询字符串,将其拆分成小写的分词,只要已分析的字段中包含词条的任意一个,或全部包含,就匹配查询条件,返回该文档;如果不包含任意一个分词,表示没有任何文档匹配查询条件。

    While the full text queries will analyze the query string before executing, the term-level queries operate on the exact terms that are stored in the inverted index.

    举个例子,创建索引,并索引文档:

    PUT my_index
    {
      "mappings": {
        "my_type": {
          "properties": {
            "full_text": {
              "type":  "string" 
            },
            "exact_value": {
              "type":  "string",
              "index": "not_analyzed" 
            }
          }
        }
      }
    }
    
    PUT my_index/my_type/1
    {
      "full_text":   "Quick Foxes!", 
      "exact_value": "Quick Foxes!"  
    }
    View Code

    字段full_text 默认值被分析的(analyzed),字段exact_value显式设置不被分析,索引文档的结果是:在倒排索引中,字段full_text包含两个分词:quick和foxes,分词都是小写的;而exact_value由于未被分析,只是整个短语“Quick Foxes!”,只能进行完全匹配,在查询条件中,少一个字符或多一个字符,甚至大小写不同都不能匹配。

    1,对未分析的字段进行词条查询

    GET my_index/my_type/_search
    {
      "query": {
        "term": {
          "exact_value": "Quick Foxes!" 
        }
      }
    }

    对于"exact_value": "Quick Foxes!" ,文档匹配该查询条件,如果将查询条件修改为"exact_value": "Quick Foxes",或"exact_value": "Quick",那么文档值不匹配查询条件,不会返回任何文档。  

    2,对已分析(analyzed)的字段进行词条查询

    GET my_index/my_type/_search
    {
      "query": {
        "term": {
          "full_text": "Quick Foxes!" 
        }
      }
    }

    对于查询条件 "full_text": "Quick Foxes!",不会返回任何文档,词条查询不会分析"Quick Foxes!",对于已分析的字段中,只有小写的单个词条,这些分词都不会匹配含有多个分词的词条。修改查询条件,"full_text": "quick",由于文档中包含该分词,因此文档匹配查询条件。

    3,对已分析的字段进行全文查询

    GET my_index/my_type/_search
    {
      "query": {
        "match": {
          "full_text": "Quick Foxes!" 
        }
      }
    }

    对于全文查询条件 "full_text": "Quick Foxes!",ElasticSearch引擎首先分析查询字符串,将其拆分成两个小写的分词:quick 和 foxes,由于字段full_text中包含这两个分词,因此,文档匹配匹配(match)查询。

    二,单词条查询

    对于单个词条,对eventname字段进行查询,由于该字段是被索引和分析(analyzed)的,因此,分词之后,该字段只包含小写的分词。

    如果词条查询写成"eventname":"Azure",那么将匹配不到任何文档,ElastiSearch引擎返回空的hits数组。

    POST /_search -d
    {  
       "from":10,
       "size":5,
       "query":{  
          "term":{  
             "eventname":"azure"
          }
       }
    }

    三,多词条(terms)查询

    多词条(terms)查询的查询条件是一个词条数组,只要文档匹配任意一个词条,就匹配查询条件。

    POST /_search -d
    {  
       "from":10,
       "size":5,
       "query":{  
          "terms":{  
             "eventname":["azure","aws"]
          }
       }
    }

    四,范围查询

    范围查询,是指查询字段值匹配一定的范围的文档:

    {
        "range" : {
            "age" : {
                "gte" : 10,
                "lte" : 20,
                "boost" : 2.0
            }
        }
    }

    范围查询使用的比较操作符:

    • gte:大于或等于(Greater-than or equal to)
    • gt:大于(Greater-than)
    • lte:小于或等于(Less-than or equal to)
    • lt:小于(Less-than)

    五,前缀匹配查询

    前缀匹配查询是指,文档的字段包含以指定的字符(不会被分析)为前缀的分词,前缀匹配适用于已分析字段,只能匹配单个分词的前缀;也适用于未被分析的字段,这样,字符串将从原始值的第一个字符开始前缀匹配,例如:"exact_value": "Qui" 

    {
      "query": {
        "prefix": {
          "full_text": "qu" 
        }
      }
    }

    六,通配符匹配查询

    ElsticSearch支持的通配符(wildcard)有2个,分别是:

    • *:0个或多个任意字符
    • ?:任意单个字符

    在通配符查询中,ElasticSearch引擎不会分析查询字符串,当文档的字段匹配通配符查询条件时,文档匹配。通配符查询会使查询性能变差,为了提高查询性能,推荐:查询字符串不要以通配符开头,只在查询字符串中间或末尾使用通配符。

    {
      "query": {
        "wildcard": {
          "full_text": "qu*k" 
        }
      }
    }

    七,正则表达式查询

    ElasticSearch引擎支持正则表达式(RegExp)查询,对词条进行查询,这就意味着,在已分析(analyzed)的字符字段上,只能匹配单个分词的正则表达式,引擎把正则表达式应用到字符串字段的分词中,而不是应用到字段最原始的文本:

    Elasticsearch will apply the regexp to the terms produced by the tokenizer for that field, and not to the original text of the field.

    {
      "query": {
        "regexp": {
          "full_text": "qu[ic]{2}k" 
        }
      }
    }

    如果想对字符串字段的原始文本执行正则表达式匹配,可以在不分析(not_analyzed)的字段上执行正则表达式查询,注意,字符的大小写。

    {
      "query": {
        "regexp": {
          "exact_value": "Qui.*" 
        }
      }
    }

    参考文档:

    Elasticsearch Reference [2.4] » Query DSL » Term level queries

    Elasticsearch Reference [2.4] » Query DSL

  • 相关阅读:
    Java实现 LeetCode 394 字符串解码
    Java实现 LeetCode 394 字符串解码
    Java实现 LeetCode 392 判断子序列
    Java实现 LeetCode 392 判断子序列
    Java实现 LeetCode 392 判断子序列
    Java实现 LeetCode 391 完美矩形
    Java实现 LeetCode 391 完美矩形
    Java实现 LeetCode 391 完美矩形
    Java实现 LeetCode 390 消除游戏
    Java实现 LeetCode 390 消除游戏
  • 原文地址:https://www.cnblogs.com/ljhdo/p/4551490.html
Copyright © 2011-2022 走看看