目錄
1 term query - 索引詞檢索
1.1 term query - 不分詞檢索
term query
: 把檢索串當作一個整體來執行檢索, 即不會對檢索串分詞.
term是完全匹配檢索, 要用在不分詞的欄位上, 如果某個field在對映中被分詞了, term檢索將不起作用.
所以, 不分詞的field, 要在mapping中設定為不分詞.
—— ES 5.x之後, 為每個text型別的欄位新增了名為keyword的子欄位, 是不分詞的, 預設保留256個字元.
—— 可以使用keyword欄位進行term檢索. 示例:
GET shop/_search
{
"query": {
"term": {
"name.keyword": "Java程式設計思想"
}
}
}
1.2 terms query - in檢索
terms
, 相當於多個term
檢索, 類似於SQL中in關鍵字的用法, 即在某些給定的資料中檢索:
GET shop/_search
{
"query": {
"terms": {
"name.keyword": [
"Java程式設計思想", "Java併發程式設計的藝術"
]
}
}
}
2 prefix query - 字首檢索
prefix query
, 就是字首檢索. 比如商品name中有多個以"Java"開頭的document, 檢索字首"Java"時就能檢索到所有以"Java"開頭的文件.
—— 掃描所有倒排索引, 效能較差.
GET shop/_search
{
"query": {
"prefix": { "name": "java" }
}
}
3 wildcard query - 萬用字元檢索
掃描所有倒排索引, 效能較差.
GET shop/_search
{
"query": {
"wildcard": { "name": "ja*" }
}
}
4 regexp query - 正則檢索
掃描所有倒排索引, 效能較差.
GET shop/_search
{
"query": {
"regexp": { "name": "jav[a-z]*" }
}
}
5 fuzzy query - 糾錯檢索
fuzziness
的預設值是2 —— 表示最多可以糾錯兩次.
說明: fuzziness
的值太大, 將削弱檢索條件的作用, 也就是說糾錯次數太多, 就會導致限定檢索結果的檢索條件被改變, 失去了限定作用.
示例: 檢索name中包含"Java"的文件, Java中缺失了一個字母a:
GET shop/_search
{
"query": {
"match": {
"name": {
"query": "Jav",
"fuzziness": 1,
"operator": "and"
}
}
}
}
6 boost評分權重 - 控制文件的優先順序別
通過boost引數, 令滿足某個條件的文件的得分更高, 從而使得其排名更靠前.
GET shop/_search
{
"query": {
"bool": {
"must": [
{ "match": { "name": "程式設計思想"} }
],
"should": [
{
"match": {
"name": {
"query": "藝術",
"boost": 2 // 提升評分權重
}
}
}
]
}
}
}
7 dis_max的用法 - best fields策略
一般檢索中, 檢索條件會被分詞, bool檢索構建多個子檢索 (must
| must_not
| should
| filter
), 這些子檢索可能會包含多個field. 這時:
多個子檢索的field各自匹配少量關鍵字的文件的分數 > 某個子檢索的field匹配大量關鍵字的文件的分數.
7.1 dis_max的提出
如果我們希望檢索結果中 (檢索串被分詞後的) 關鍵字匹配越多, 這樣的文件就越靠前, 而不是多個子檢索中匹配少量分詞的文件靠前.
⇒ 此時可以使用dis_max和tie_breaker.
tie_breaker的值介於0~1之間, Elasticsearch將
bool檢索的分數 * tie_breaker
的結果與dis_max的最高分進行比較, 除了取dis_max的最高分以外, 還會考慮其他的檢索結果的分數.
7.2 使用示例
為了增加精準度, 常用的是配合boost、minimum_should_match等引數控制檢索結果.
GET shop/_search
{
"query": {
"dis_max": {
"queries": [
{ "match": { "name": "虛擬機器" } },
{ "match": { "desc": "經典" } }
],
"tie_breaker": 0.2 // 對同時滿足的文件的分值進行提升
}
}
}
GET shop/_search
{
"query": {
"dis_max": {
"queries": [
{
"match": {
"name": {
"query": "虛擬機器",
"minimum_should_match": "50%",
"boost": 2
}
}
},
{
"match": {
"desc": {
"query": "經典",
"minimum_should_match": "50%",
"boost": 3
}
}
}
],
"tie_breaker": 0.3
}
}
}
8 exist query - 存在檢索, 已過期
這是Elasticsearch 2.x中的API, 後續版本不再支援.
9 複雜檢索的使用範例
9.1 多條件過濾 - 包含
檢索出版時間在2012-07之後, 且至少滿足下述條件中一個的文件:
a. 名稱(name)中包含"併發";
b. 描述(desc)中包含"java";
c. 出版社(publisher)名稱中不包含"電子".
GET shop/_search
{
"query": {
"bool": {
"filter": { // 按時間過濾
"range": {
"date": {"gte": "2012-07"}
}
},
"should": [ // 可匹配, 可不匹配
{
"match": { "name": "併發" }
},
{
"bool": {
"must": { // 必須匹配
"match": { "desc": "java" }
},
"must_not": { // 不能匹配
"match": { "publisher": "電子" }
}
}
}
],
"minimum_should_match": 1 // 至少滿足should中的一個條件
}
},
// 自定義排序
"sort": [
{ "price": { "order": "desc" } }
]
}
注意: 排序的欄位最好是數字, 或日期, 因為字串欄位會被分詞, ES會通過分詞後的某個詞去排序, 結果難以預測.
9.2 多條件拼接 - 包含+範圍+排序
匹配檢索: name中包含"java"卻不包含"虛擬機器";
範圍檢索: 價格大於50、小於80;
結果排序: 按照價格升序排序.
GET shop/_search
{
"query": {
"bool": {
"must": { // 必須匹配
"match": { "name": "java" }
},
"must_not": { // 必須不匹配
"match": { "name": "虛擬機器" }
},
"filter": {
"range": {
"price": {
"gte": 40,
"lte": 80,
"boost": 2.0 // 設定得分的權重值(提升值), 預設是1.0
}
}
}
}
}
}
關於範圍檢索的使用, 請參考下篇文章: ES 22 - Elasticsearch對數值或日期型別進行範圍檢索
9.3 定製檢索結果的排序規則
(1) 預設排序規則:
ES預設是按檢索結果的分值(_score)降序排列的.
某些情況下, 可能存在無實際意義的_score, 比如filter時所有_score的值都相同:
GET website/_search
{
"query": {
"bool": {
"filter": {
"term": {
"author_id": 5520 // 此時所有符合條件的_score都為0
}
}
}
}
}
// 或通過constant_score過濾:
GET website/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"author_id": 5520 // 此時所有符合條件的_score都為1
}
}
}
}
}
(2) 定製排序規則:
GET website/_search
{
"query": {
"constant_score": {
"filter": {
"term": {
"author_id": 5520
}
}
}
},
"sort": [
{
"post_date": { "order": "asc" }
}
]
}
版權宣告
出處: 部落格園 馬瘦風的部落格(https://www.cnblogs.com/shoufeng)
感謝閱讀, 如果文章有幫助或啟發到你, 點個[好文要頂?] 或 [推薦?] 吧?
本文版權歸博主所有, 歡迎轉載, 但 [必須在文章頁面明顯位置標明原文連結], 否則博主保留追究相關人員法律責任的權利.