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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM