Elasticsearch——查詢//過濾詳細總結


 

https://blog.csdn.net/donghaixiaolongwang/article/details/57418306

 

查詢分為兩種:字符串查詢和DSL查詢

1、字符串查詢詳細總結,此種方法一般用於簡單測試。想要更加靈活,功能更加強大的查詢功能還是得用DSL。但是這個字符串查詢用起來還是挺方便的。切記不可將這種查詢語句給你的客戶。除非這個客戶是你非常信任的。要不然這種語句會給你的集群帶來致命的危險!!!!!

 

1>GET /index/tweet/_search?q=tweet:elasticsearch  #查詢index索引 (相當於數據庫)、tweet類型(相當於數據庫中的表)、tweet字段中包含elasticsearch關鍵詞的文章。

 

2>GET /index/tweet/_search?q=%2Bname%3Ajohn+%2Btweet%3Amary   #+name:john +tweet:mary  查詢name字段包含john 同時tweet字段包含mary。%2B 是“+”,%3A是“:”

"+"前綴表示語句匹配條件必須被滿足。類似的"-"前綴表示條件必須不被滿足。所有條件如果沒有+-表示是可選的——匹配越多,相關的文檔就越多。

 

3>更復雜的例子:

 

  • name字段包含"mary""john"
  • date晚於2014-09-10
  • _all字段包含"aggregations""geo"

 

+name:(mary john) +date:>2014-09-10 +(aggregations geo)

 

編碼后的查詢字符串變得不太容易閱讀:

GET /index/tweet/_search?q=%2Bname%3A(mary+john)+%2Bdate%3A%3E2014-09-10+%2B(aggregations+geo)

 

4>其他常用參數使用舉

 

GET /index/tweet/_search?q=%2Bdate%3A%3E2014-09-10+%2Bname1%3A(A+B+C)+%2Dname2%3A(D+E+F)+name3%3A(G+H+I)&from=0&size=3 

##查詢index索引tweet類型中date字段日期在2014-09-10以后,同時name1字段必須含有A或者B或者C中的一個,同時name2字段不能包含有D或者E或者F中的任意一個,
如果name3字段中包含了G或者H或者I那么他就會排在前邊,包含的G、H、I、越多排名越靠前。並且只給我返回從0-3的3個結果。
 

附加:更加詳細得字符串查詢參數請參看:https://www.elastic.co/guide/en/elasticsearch/reference/2.4/search-uri-request.html 

           “+”號“-”號和其他符號URL對照表參見:http://www.cnblogs.com/kobe8/p/4030396.html

 

 

 

##########################################################

##################################################################

2、DSL查詢總結,此處才是主要的。一定要多看幾遍並且盡量用項目來練習,不然不能靈活使用。多看查詢和過濾的語句,較常用。

英文好的參看官方DSL語句。參看網址(權威):https://www.elastic.co/guide/en/elasticsearch/reference/2.4/query-dsl-match-query.html

偷懶的看下邊:個人的使用經驗,和參考別人的。僅供參考

 

 

下邊內容多摘自網站(下方列出了較常用的查詢語句,其他更為專有的查詢語句請自行查詢。):https://es.xiaoleilu.com/080_Structured_Search/10_compoundfilters.html

最重要的查詢過濾語句

 

term 過濾

 

term主要用於精確匹配哪些值,比如數字,日期,布爾值或not_analyzed的字符串(未經分析的文本數據類型):

  1.  
    { "term": { "age": 26 }}
  2.  
    { "term": { "date": "2014-09-01" }}
  3.  
    { "term": { "public": true }}
  4.  
    { "term": { "tag": "full_text" }}
例子:注意我用的是ik分詞器。你最好先用英文來搞。查一個單詞

GET /ik2_index/ik_type6/_search
{
  "query": {
    "term": {
      "content1": "AAA"
    }
  }
}

 

 

terms 過濾

 

terms 跟 term 有點類似,但 terms 允許指定多個匹配條件。 如果某個字段指定了多個值,那么文檔需要一起去做匹配:

+
  1.  
    {
  2.  
    "terms": {
  3.  
    "tag": [ "search", "full_text", "nosql" ]
  4.  
    }
  5.  
    }
例子:注意我用的是ik分詞器。你最好先用英文來搞。查一個單詞

GET /ik2_index/ik_type6/_search
{
  "query": {
    "terms": {
        "content1": [ "AAA", "BBB", "美國" ]
        }
  }
}

 

 

range 過濾

 

range過濾允許我們按照指定范圍查找一批數據:

  1.  
    {
  2.  
    "range": {
  3.  
    "age": {
  4.  
    "gte": 20,
  5.  
    "lt": 30
  6.  
    }
  7.  
    }
  8.  
    }
例子:

GET /ik2_index/ik_type6/_search
{
  "query": {
    "range": {
        "age": {
            "gte":  20,
            "lt":   30
        }
    }
  }
}

 

圍操作符包含:

gt :: 大於

gte:: 大於等於

lt :: 小於

lte:: 小於等於

 

 

bool 過濾

 

bool 過濾可以用來合並多個過濾條件查詢結果的布爾邏輯,它包含一下操作符:

must :: 多個查詢條件的完全匹配,相當於 and

must_not :: 多個查詢條件的相反匹配,相當於 not

should :: 至少有一個查詢條件匹配, 相當於 or

這些參數可以分別繼承一個過濾條件或者一個過濾條件的數組:還可以繼續嵌套

  1.  
    {
  2.  
    "bool": {
  3.  
    "must": { "term": { "folder": "inbox" }},
  4.  
    "must_not": { "term": { "tag": "spam" }},
  5.  
    "should": [
  6.  
    { "term": { "starred": true }},
  7.  
    { "term": { "unread": true }}
  8.  
    ]
  9.  
    }
  10.  
    }

例子:

GET /ik2_index/ik_type6/_search
{
  "query": {
    "bool": {
      "must": {
        "term": {
          "folder": "inbox"
        }
      },
      "must_not": {
        "term": {
          "tag": "spam"
        }
      },
      "should": [
        {
          "term": {
            "starred": true
          }
        },
        {
          "term": {
            "unread": true
          }
        }
      ]
    }
  }
}

 

附加:更多過濾參看網址:https://segmentfault.com/a/1190000004429689

 

 

 

match 查詢

 

match查詢是一個標准查詢,不管你需要全文本查詢還是精確查詢基本上都要用到它。

如果你使用 match 查詢一個全文本字段,它會在真正查詢之前用分析器先分析match一下查詢字符:

  1.  
    {
  2.  
    "match": {
  3.  
    "tweet": "About Search"
  4.  
    }
  5.  
    }

如果用match下指定了一個確切值,在遇到數字,日期,布爾值或者not_analyzed 的字符串時,它將為你搜索你給定的值:

  1.  
    { "match": { "age": 26 }}
  2.  
    { "match": { "date": "2014-09-01" }}
  3.  
    { "match": { "public": true }}
  4.  
    { "match": { "tag": "full_text" }}

提示: 做精確匹配搜索時,你最好用過濾語句,因為過濾語句可以緩存數據。

不像我們在《簡單搜索》中介紹的字符查詢,match查詢不可以用類似"+usid:2 +tweet:search"這樣的語句。 它只能就指定某個確切字段某個確切的值進行搜索,而你要做的就是為它指定正確的字段名以避免語法錯誤。

例子1:

GET /ik2_index/ik_type6/_search
{
  "query": {
     "match": {
            "age": 26
          }
  }
}

例子2:多個match可以連在一起來搞,挺爽吧。里邊得內容必須全部成立。當然你可以放到must_not(都不能成立)或者should(能成立的排在前邊)中GET /ik2_index/ik_type6/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "age": 26
          }
        },
        {
          "match": {
            "date": "2014-09-01"
          }
        },
        {
          "match": {
            "public": true
          }
        },
        {
          "match": {
            "tag": "full_text"
          }
        }
      ]
    }
  }
}

 

#在沒有must句子時,should句子中至少有一個成立。所以現在是或的關系

GET /_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "War and Peace"
          }
        },
        {
          "match": {
            "author": "Leo Tolstoy"
          }
        }
      ]
    }
  }
}

 

 

例子3:GET /my_index/my_type/_search
{
  "query": {
    "match": {
      "title": "BROWN DOG!"
    }
  }
}

 

 

match 查詢提高精度

 

匹配包含任意個數查詢關鍵字的文檔可能會得到一些看似不相關的結果,這是一種霰彈策略(shotgun approach)。然而我們可能想得到包含所有查詢關鍵字的文檔。換句話說,我們想得到的是匹配'brown AND dog'的文檔,而非'brown OR dog'

match查詢接受一個'operator'參數,默認值為or。如果要求所有查詢關鍵字都匹配,可以更改參數值為and

  1.  
    GET /my_index/my_type/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "match": {
  5.  
    "title": { <1>
  6.  
    "query": "BROWN DOG!",
  7.  
    "operator": "and"
  8.  
    }
  9.  
    }
  10.  
    }
  11.  
    }

 

 
           
          

match 查詢控制精度(莫要小看此處,可用於相似文章判斷查詢)

在 all 和 any 之間的選擇有點過於非黑即白。如果用戶指定了5個查詢關鍵字,而一個文檔只包含了其中的4個?將'operator'設置為'and'會排除這個文檔。

有時這的確是用戶想要的結果。但在大多數全文檢索的使用場景下,用戶想得到相關的文檔,排除那些不太可能相關的文檔。換句話說,我們需要介於二者之間的選項。

match查詢有'minimum_should_match'參數,參數值表示被視為相關的文檔必須匹配的關鍵詞個數。參數值可以設為整數,也可以設置為百分數。因為不能提前確定用戶輸入的查詢關鍵詞個數,使用百分數也很合理。

  1.  
    GET /my_index/my_type/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "match": {
  5.  
    "title": {
  6.  
    "query": "quick brown dog",
  7.  
    "minimum_should_match": "75%"
  8.  
    }
  9.  
    }
  10.  
    }
  11.  
    }

'minimum_should_match'被設置為百分數時,查詢進行如下:在上面的例子里,'75%'會被下舍為'66.6%',也就是2個關鍵詞。不論參數值為多少,進入結果集的文檔至少應匹配一個關鍵詞。


 

 
          

短語匹配(Phrase Matching) ##match_phrase查詢。比較有用。用到match的地方都可能用到。

這個查詢流程是:先將查詢內容按照查詢字段的分詞器進行分詞,之后所有分詞結果,必須都在該字段中能查到的文章才算合格的。 GET  /my_index/my_type/_search { "query": { "match_phrase": { "title": "quick brown fox" } } }

 

match_phrase查詢優化

GET ik2_index/ik_type8/_search
{
  "query": {
    "match_phrase": {
      "content2": {
      "query": "quick fox",
      "slop": 2
      }
      
      
    }
  }
}

注釋:slop參數可以給match_phrase一些自由度。slop解釋參看https://www.elastic.co/guide/en/elasticsearch/guide/current/slop.html

 

 

短語匹配之前綴查詢(match_phrase_prefix)查詢期間的即時搜索(Query-time Search-as-you-type)

 

 

此查詢和match_phrase查詢的工作方式基本相同,除了它會將查詢字符串中的最后一個單詞當做一個前綴。換言之,前面的例子會查找以下內容:

  • johnnie
  • 緊接着的是walker
  • 緊接着的是以bl開頭的單詞

max_expansions參數會控制能夠匹配該前綴的詞條的數量。它會找到首個以bl開頭的詞條然后開始收集(以字母表順序)直到所有以bl開頭的詞條都被遍歷了或者得到了比max_expansions數量多1的時候才會結束(相同的詞條算一個)。這個參數在生產環境一定要限制,否則不會有好的體驗。不要忘了在用戶每敲入一個字符的時候,該查詢就要被執行一次,因此它的速度需要快。如果第一個結果集不符合用戶的期望,那么他們就會繼續輸入直到得到他們需要的結果。

 

GET ik2_index/ik_type8/_search
{
  "query": {
    "match_phrase_prefix": {
      "content2": {
      "query": "johnnie walker bl",
      "max_expansions": 5
      }
      
      
    }
  }
}

 

 

prefix查詢,查找某個字段中所有分詞,只要有分詞項是以yell開頭的。那這個文檔就是符合我們要求的。

GET ik2_index/ik_type8/_search
{
  "query": {
    "prefix": {
      "content2": "yell"     
    }
  }
}

 

 

 

 

multi_match 查詢

 

multi_match查詢允許你做match查詢的基礎上同時搜索多個字段:

  1.  
    {
  2.  
    "multi_match": {
  3.  
    "query": "full text search",
  4.  
    "fields": [ "title", "body" ]
  5.  
    }
  6.  
    }

例子:同時在一個字段中搜索多個term關鍵詞,關鍵詞之間是或的關系字段之間也是或得關系。

GET /ik2_index/ik_type6/_search
{
  "query": {
    "multi_match": {
      "query": "full text search",
      "fields": [
        "title",
        "body"
      ]
    }
  }
}

 

 

更加精細得multi_match 查詢解釋

 

multi_match查詢提供了一個簡便的方法用來對多個字段執行相同的查詢。

提示:存在幾種類型的multi_match查詢:best_fields,most_fields以及cross_fields。

默認情況下,該查詢以best_fields類型執行,它會為每個字段生成一個match查詢,然后將這些查詢包含在一個dis_max查詢中。下面的dis_max查詢:

  1.  
    {
  2.  
    "dis_max": {
  3.  
    "queries": [
  4.  
    {
  5.  
    "match": {
  6.  
    "title": {
  7.  
    "query": "Quick brown fox",
  8.  
    "minimum_should_match": "30%"
  9.  
    }
  10.  
    }
  11.  
    },
  12.  
    {
  13.  
    "match": {
  14.  
    "body": {
  15.  
    "query": "Quick brown fox",
  16.  
    "minimum_should_match": "30%"
  17.  
    }
  18.  
    }
  19.  
    },
  20.  
    ],
  21.  
    "tie_breaker": 0.3
  22.  
    }
  23.  
    }

可以通過multi_match簡單地重寫如下:

  1.  
    {
  2.  
    "multi_match": {
  3.  
    "query": "Quick brown fox",
  4.  
    "type": "best_fields", <1>
  5.  
    "fields": [ "title", "body" ],
  6.  
    "tie_breaker": 0.3,
  7.  
    "minimum_should_match": "30%" <2>
  8.  
    }
  9.  
    }
  10.  
     

<1> 注意到以上的type屬性為best_fields。

<2> minimum_should_match和operator參數會被傳入到生成的match查詢中。

 

在字段名中使用通配符:

字段名可以通過通配符指定:任何匹配了通配符的字段都會被包含在搜索中。你可以通過下面的查詢來匹配book_title,chapter_title以及section_title字段:

  1.  
    {
  2.  
    "multi_match": {
  3.  
    "query": "Quick brown fox",
  4.  
    "fields": "*_title"
  5.  
    }
  6.  
    }

加權個別字段:

個別字段可以通過caret語法(^)進行加權:僅需要在字段名后添加^boost,其中的boost是一個浮點數:

  1.  
    {
  2.  
    "multi_match": {
  3.  
    "query": "Quick brown fox",
  4.  
    "fields": [ "*_title", "chapter_title^2" ] <1>
  5.  
    }
  6.  
    }

<1> chapter_title字段的boost值為2,而book_title和section_title字段的boost值為默認的1。


 

 

 

 

 

 

 

bool 查詢

 

bool 查詢與 bool 過濾相似,用於合並多個查詢子句。不同的是,bool 過濾可以直接給出是否匹配成功, 而bool 查詢要計算每一個查詢子句的_score (相關性分值)。

must:: 查詢指定文檔一定要被包含。

must_not:: 查詢指定文檔一定不要被包含。

should:: 查詢指定文檔,有則可以為文檔相關性加分。

以下查詢將會找到 title 字段中包含 "how to make millions",並且 "tag" 字段沒有被標為spam。 如果有標識為 "starred" 或者發布日期為2014年之前,那么這些匹配的文檔將比同類網站等級高:

  1.  
    {
  2.  
    "bool": {
  3.  
    "must": { "match": { "title": "how to make millions" }},
  4.  
    "must_not": { "match": { "tag": "spam" }},
  5.  
    "should": [
  6.  
    { "match": { "tag": "starred" }},
  7.  
    { "range": { "date": { "gte": "2014-01-01" }}}
  8.  
    ]
  9.  
    }
  10.  
    }

例子:

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

 

 

bool 查詢精度控制

 

所有的 must 子句必須匹配, 並且所有的 must_not 子句必須不匹配, 但是多少should 子句應該匹配呢? 默認的,不需要匹配任何should 子句,一種情況例外:如果沒有must子句,就必須至少匹配一個should子句。

像我們控制match查詢的精度一樣,我們也可以通過minimum_should_match參數控制多少should子句需要被匹配,這個參數可以是正整數,也可以是百分比。

  1.  
    GET /my_index/my_type/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "bool": {
  5.  
    "should": [
  6.  
    { "match": { "title": "brown" }},
  7.  
    { "match": { "title": "fox" }},
  8.  
    { "match": { "title": "dog" }}
  9.  
    ],
  10.  
    "minimum_should_match": 2 <1>
  11.  
    }
  12.  
    }
  13.  
    }

<1> 這也可以用百分比表示

 

bool 查詢精度控制——提高查詢得分

 

 

我們可以在任何查詢子句中指定一個boost值來控制相對權重,默認值為1。一個大於1的boost值可以提高查詢子句的相對權重。因此我們的查詢:

  1.  
    GET /_search
  2.  
    {
  3.  
    "query": {
  4.  
    "bool": {
  5.  
    "must": {
  6.  
    "match": { (1)
  7.  
    "content": {
  8.  
    "query": "full text search",
  9.  
    "operator": "and"
  10.  
    }
  11.  
    }
  12.  
    },
  13.  
    "should": [
  14.  
    { "match": {
  15.  
    "content": {
  16.  
    "query": "Elasticsearch",
  17.  
    "boost": 3 (2)
  18.  
    }
  19.  
    }},
  20.  
    { "match": {
  21.  
    "content": {
  22.  
    "query": "Lucene",
  23.  
    "boost": 2 (3)
  24.  
    }
  25.  
    }}
  26.  
    ]
  27.  
    }
  28.  
    }
  29.  
    }
  1. 這些查詢子句的boost值為默認值1
  2. 這個子句是最重要的,因為他有最高的boost值。
  3. 這個子句比第一個查詢子句的要重要,但是沒有“Elasticsearch”子句重要。

注意:

  1. boost參數用於提高子句的相對權重(boost值大於1)或者降低子句的相對權重(boost值在0-1之間),但是提高和降低並非是線性的。換句話說,boost值為2並不能夠使結果變成兩部的得分。

  2. 另外,boost值被使用了以后新的得分是標准的。每個查詢類型都會有一個獨有的標准算法,算法的詳細內容並不在本書的范疇。簡單的概括一下,一個更大的boost值可以得到一個更高的得分。

  3. 如果你自己實現了沒有基於TF/IDF的得分模型,但是你想得到更多的對於提高得分過程的控制,你可以使用function_score查詢來調整一個文檔的boost值而不用通過標准的步驟。

 

 

 

 

 

 

最佳字段查詢###dis_max查詢

 

我們可以使用dis_max查詢(Disjuction Max Query)。


這種查詢方式可以使你的查詢結果更加精准,體現在:某一個字段同時包含 Brown fox兩個詞,將會比兩個字段各自包含Brown fox中的任意一個詞得分高。這樣可以使查詢結果更加精准。這主要原因還在與查詢中的分數計算方法。相關性分數的計算方法參見:https://es.xiaoleilu.com/056_Sorting/90_What_is_relevance.html

  1.  
    {
  2.  
    "query": {
  3.  
    "dis_max": {
  4.  
    "queries": [
  5.  
    { "match": { "title": "Brown fox" }},
  6.  
    { "match": { "body": "Brown fox" }}
  7.  
    ]
  8.  
    }
  9.  
    }
  10.  
    }

注釋:為什么上邊得dis_max查詢會得到更相關的結果。如果你不是用上邊的得語句而用下邊的這個,就會看到兩個字段各自包含一個詞,會比一個字段同時包含兩個詞得分高。顯然上邊得查詢准確性更相關。注意使用的場景,遇見了在用這種查詢。

 

bool查詢是如何計算得到其分值的:

  • 1.運行should子句中的兩個查詢
  • 2.相加查詢返回的分值
  • 3.將相加得到的分值乘以匹配的查詢子句的數量
  • 4.除以總的查詢子句的數量

GET /_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "Brown fox"
          }
        },
        {
          "match": {
            "body": "Brown fox"
          }
        }
      ]
    }
  }
}

 

最佳字段查詢###dis_max查詢#####最佳字段查詢的調優

 

 

tie_breaker  這意味着另一個字段在計算得分時將不會被完全丟棄而是有所保留

 

但是,將其它匹配的查詢子句考慮進來也是可能的。通過指定tie_breaker參數:

  1.  
    {
  2.  
    "query": {
  3.  
    "dis_max": {
  4.  
    "queries": [
  5.  
    { "match": { "title": "Quick pets" }},
  6.  
    { "match": { "body": "Quick pets" }}
  7.  
    ],
  8.  
    "tie_breaker": 0.3
  9.  
    }
  10.  
    }
  11.  
    }

tie_breaker參數會讓dis_max查詢的行為更像是dis_max和bool的一種折中。它會通過下面的方式改變分值計算過程:

  • 1.取得最佳匹配查詢子句的_score。
  • 2.將其它每個匹配的子句的分值乘以tie_breaker。
  • 3.將以上得到的分值進行累加並規范化。

通過tie_breaker參數,所有匹配的子句都會起作用,只不過最佳匹配子句的作用更大。

提示:tie_breaker的取值范圍是0到1之間的浮點數,取0時即為僅使用最佳匹配子句(譯注:和不使用tie_breaker參數的dis_max查詢效果相同),取1則會將所有匹配的子句一視同仁。它的確切值需要根據你的數據和查詢進行調整,但是一個合理的值會靠近0,(比如,0.1 -0.4),來確保不會壓倒dis_max查詢具有的最佳匹配性質。

最多字段查詢

  1.  
    GET /my_index/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "multi_match": {
  5.  
    "query": "jumping rabbits",
  6.  
    "type": "most_fields", <1>
  7.  
    "fields": [ "title", "title.std" ]
  8.  
    }
  9.  
    }
  10.  
    }
  11.  
     

<1> 在上述查詢中,由於我們想合並所有匹配字段的分值,因此使用的類型為most_fields。這會讓multi_match查詢將針對兩個字段的查詢子句包含在一個bool查詢中,而不是包含在一個dis_max查詢中


注釋:和下邊得語句一樣

GET /_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "Brown fox"
          }
        },
        {
          "match": {
            "body": "Brown fox"
          }
        }
      ]
    }
  }
}

 

 

最多字段查詢調優

 

 

個字段對最終分值的貢獻可以通過指定boost值進行控制。比如,我們可以提升title字段來讓該字段更加重要,這也減小了其它信號字段的影響:

  1.  
    GET /my_index/_search
  2.  
    {
  3.  
    "query": {
  4.  
    "multi_match": {
  5.  
    "query": "jumping rabbits",
  6.  
    "type": "most_fields",
  7.  
    "fields": [ "title^10", "title.std" ] <1>
  8.  
    }
  9.  
    }
  10.  
    }

<1> boost=10讓title字段的相關性比title.std更重要。 計分的時候會多給title分量。

 

使用most_fields存在的問題

使用most_fields方法執行實體查詢有一些不那么明顯的問題:

  • 它被設計用來找到匹配任意單詞的多數字段,而不是找到跨越所有字段的最匹配的單詞。這將會引申出跨字段查詢方式。
  • 它不能使用operator或者minimum_should_match參數來減少低相關度結果帶來的長尾效應。這個沒轍
  • 每個字段的詞條頻度是不同的,會互相干擾最終得到較差的排序結果。多個字段值可以放到同一個字段中,這樣可以解決詞條頻度不均衡而計分不准確得問題。
  • 自定義_all字段

    元數據:_all字段中,我們解釋了特殊的_all字段會將其它所有字段中的值作為一個大字符串進行索引。盡管將所有字段的值作為一個字段進行索引並不是非常靈活。如果有一個自定義的_all字段用來索引人名,另外一個自定義的_all字段用來索引地址就更好了。

    ES通過字段映射中的copy_to參數向我們提供了這一功能:

    1.  
      PUT /my_index
    2.  
      {
    3.  
      "mappings": {
    4.  
      "person": {
    5.  
      "properties": {
    6.  
      "first_name": {
    7.  
      "type": "string",
    8.  
      "copy_to": "full_name" <1>
    9.  
      },
    10.  
      "last_name": {
    11.  
      "type": "string",
    12.  
      "copy_to": "full_name" <1>
    13.  
      },
    14.  
      "full_name": {
    15.  
      "type": "string"
    16.  
      }
    17.  
      }
    18.  
      }
    19.  
      }
    20.  
      }

    <1> first_name和last_name字段中的值會被拷貝到full_name字段中。

    有了這個映射,我們可以通過first_name字段查詢名字,last_name字段查詢姓氏,或者full_name字段查詢姓氏和名字。

    提示:first_name和last_name字段的映射和full_name字段的索引方式的無關。full_name字段會從其它兩個字段中拷貝字符串的值,然后僅根據full_name字段自身的映射進行索引。

解釋參看:知道看不明白所以給出了鏈接,我看了好幾遍才前后貫穿上。差點對不上號。https://es.xiaoleilu.com/110_Multi_Field_Search/40_Field_centric.html

 

 

跨字段查詢

GET /_validate/query?explain            #詞條peter必須出現在任一字段中,同時詞條smith也必須出現在任一字段中。這就是以詞條為中心和字段為中心得差別。解決了1、找到匹配任意單詞的多數字段,還是找到跨越所有字段的最匹配的單詞.2、查詢結果得長尾效應解決了。
{
    "query": {
        "multi_match": {
            "query":       "peter smith",
            "type":        "cross_fields",
            "operator":    "and",
            "fields":      [ "first_name", "last_name" ]
        }
    }
}

 

cross_fields類型采用了一種以詞條為中心(Term-centric)的方法,這種方法和best_fields及most_fields采用的以字段為中心(Field-centric)的方法有很大的區別。它將所有的字段視為一個大的字段,然后在任一字段中搜索每個詞條。可以把所有字段認為是一個字段,在里邊進行查詢。解決了3、詞條分布不均勻對得分得影響。


注意:這種查詢方式解決了most_fields查詢的所有3個問題。

 

跨字段查詢調優

對於first_name和last_name這類擁有近似值的字段,也許加權是不必要的,但是如果你通過title和description字段來搜索書籍,那么你或許會給予title字段更多的權重。這可以通過前面介紹的caret(^)語法來完成:

 

GET /books/_search
{
  "query": {
    "multi_match": {
      "query": "peter smith",
      "type": "cross_fields",
      "fields": [
        "title^2",
        "description"
      ]
    }
  }
}

 

 

 

 

fuzzy查詢。當用戶輸入錯誤單詞‘cirme’,能返回正確的單詞‘crime’

 

GET ik2_index/ik_type8/_search
{
  "query": {
    "fuzzy": {
      "content2": {
        "value":"quick",
        "min_similarity":1,
        "max_expansions":5
        
      }
      
    }
  }
 
}

value:要查詢的詞項。

min_similarity:默認值1,值越大需要的相似越小。

max_expansions::默認值全部。只給我返回相似的前max_expansions+1條(詞條一樣的算一條)。

 

 

Wildcard查詢,和sql的like有點相似。這個挺好用的。可以臨時查數據。

GET ik2_index/ik_type8/_search
{
  "query": {
    "wildcard": {
    "content2":"qui?k"
      
    
    }
  }
 
}

 

more_like_this查詢

GET ik2_index/ik_type8/_search
{ "from":0,
"size":3,
  "query": {
    "more_like_this": {
    "fields":["content2"],
    "like_text":"quick  fox",
    "min_term_freq": 1,
    "min_doc_freq": 1
         
    }
  }
 
}

注釋:和match_phrase_prefix相似,但是比它更靈活。這個語句能查出類似quick yellow fox   、quick black fox。相當於吧fuzzy語句用or連接起來。

其他參數保持不變。min_term_freq 指明文檔中詞項出現的最低頻率,低於該值的詞項將被省略(測試沒有作用)。min_dox_freq指明詞項必須出現在至少多少個文檔中才不被s省略(測試有作用)。max_query_terms指明生成的查詢中查詢詞項的最大數目,超過這個數目的詞項將被省略。默認為25(查詢的字符串很長時可能有用)

 

查詢與過濾條件的合並

1>、帶過濾的查詢語句,這種過濾屬於前置過濾——先過濾在查詢

GET /_search
{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "email": "business opportunity"
        }
      },
      "filter": {
        "term": {
          "folder": "inbox"
        }
      }
    }
  }
}

//多次過濾可參看

GET /_search
{
  "query": {
    "filtered": {
      "query": {
        "match": {
          "content3": "德國"
        }
      },
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "content3": "德國"
              }
            },
            {
              "term": {
                "content2": "美國"
              }
            },
            {
              "term": {
                "content1": "AAA"
              }
            }
          ]
        }
      }
    }
  }
}

//先過濾、在查詢、再過濾、在查詢

GET ik2_index/ik_type6/_search
{
  "query": {
    "filtered": {
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "content3": "德國"
              }
            },
            {
              "match": {
                "content3": "泰國"
              }
            }
          ]
        }
      },
      "filter": {
        "bool": {
          "must": [
            {
              "term": {
                "content2": "日本"
              }
            },
            {
              "term": {
                "content2": "美國"
              }
            }
          ]
        }
      }
    }
  },
  "post_filter": {
    "bool": {
      "must": [
        {
          "term": {
            "content2": "日本"
          }
        },
        {
          "term": {
            "content2": "美國"
          }
        },
        {
          "match": {
            "content1": "AAA"
          }
        },
        {
          "match": {
            "content3": "DDD"
          }
        }
      ]
    }
  }
}



 

2>、這種屬於后置過濾器

GET ik2_index/ik_type6/_search
{
  "query": {
    "match": {
      "content3": "AAA"
    }
  },
  "post_filter": {
    "term": {
          "content3": "AAA"
        }
  }
}

 

//多次過濾

GET ik2_index/ik_type6/_search
{
  "query": {
    "match": {
      "content3": "BBB"
    }
  },
  "post_filter": {
    "bool": {
      "must": [
        {
          "term": {
            "content3": "德國"
          }
        },
        {
          "term": {
            "content2": "美國"
          }
        },
        {
          "term": {
            "content1": "AAA"
          }
        }
      ]
    }
  }
}

//先查詢、再過濾、再查詢

GET ik2_index/ik_type6/_search
{
 
 
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "content3": "德國"
          }
        },
        {
          "match": {
            "content3": "泰國"
          }
        }
      ]
    }
  },
  "post_filter": {
    "bool": {
       "must": [
            {
              "term": {
                "content2": "日本"
              }
            },
            {
              "term": {
                "content2": "美國"
              }
            },
             {
              "match": {
                "content1": "GGG"
              }
            },
            {
              "match": {
                "content3": "AAA"
              }
            }
          ]
    }
  }
}

 

 

 

 

其他可能有用的查詢:

 

檢索文檔是否存在

如果你想做的只是檢查文檔是否存在——你對內容完全不感興趣——使用HEAD方法來代替GETHEAD請求不會返回響應體,只有HTTP頭:

curl -i -XHEAD http://localhost:9200/website/blog/123 

Elasticsearch將會返回200 OK狀態如果你的文檔存在:

  1.  
    HTTP/ 1.1 200 OK
  2.  
    Content-Type: text/plain; charset=UTF -8
  3.  
    Content-Length: 0

如果不存在返回404 Not Found

curl -i -XHEAD http://localhost:9200/website/blog/124 
  1.  
    HTTP/ 1.1 404 Not Found
  2.  
    Content-Type: text/plain; charset=UTF -8
  3.  
    Content-Length: 0

當然,這只表示你在查詢的那一刻文檔不存在,但並不表示幾毫秒后依舊不存在。另一個進程在這期間可能創建新文檔。

 

一次檢索多個文檔

POST /_mget
{
   "docs" : [
      {
         "_index" : "website",
         "_type" :  "blog",
         "_id" :    2
      },
      {
         "_index" : "website",
         "_type" :  "pageviews",
         "_id" :    1,
         "_source": "views"
      }
   ]

 

附加:本文內容多摘自網站:可自行學習。畢竟總結不全。這篇主要總結了查詢。時間不早了,模糊查詢后邊補上。https://es.xiaoleilu.com/030_Data/20_Exists.html

 


免責聲明!

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



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