Elasticsearch 7.x 深入【4】DSL查詢【二】全文級(jí)別的查詢

1. 借鑒

極客時(shí)間 阮一鳴老師的Elasticsearch核心技術(shù)與實(shí)戰(zhàn)
ElasticSearch7+Spark構(gòu)建高相關(guān)性搜索服務(wù)&千人千面推薦系統(tǒng)
官方文檔 full-text-queries
Elasticsearch Query DSL之全文檢索(Full text queries)上篇
Elasticsearch Query DSL之全文檢索(Full text queries)下篇
Elasticsearch自定義分詞塔猾,從一個(gè)問題說開去
Elasticsearch之match_phrase小坑記錄
官方文檔 slop
Elasticsearch - 短語匹配(match_phrase)以及slop參數(shù)
網(wǎng)名生成器

2. 開始

基于全文本的查詢

  • 基于全文本的查詢有以下幾種:match,match phrase惶岭,match bool prefix栅贴,match phrase prefix涩禀,multi match,query string,simple query string羔沙。
  • 會(huì)對(duì)輸入進(jìn)行分詞這一點(diǎn)要注意

我們創(chuàng)建一些數(shù)據(jù)供以后使用

# 創(chuàng)建索引
PUT /actors
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "ik_max_word", 
        "fields": {
          "keyword": {
            "type": "keyword"
          }
        }
      }
    }
  }
}
# 添加數(shù)據(jù)[名字隨機(jī)生成的,如有雷同厨钻,純屬巧合]
PUT /_bulk
{"index": {"_index": "actors", "_id": 1}}
{"name": "陳宛曼"}
{"index": {"_index": "actors", "_id": 2}}
{"name": "陳浩南"}
{"index": {"_index": "actors", "_id": 3}}
{"name": "司徒浩南"}
{"index": {"_index": "actors", "_id": 4}}
{"name": "易白竹"}
{"index": {"_index": "actors", "_id": 5}}
{"name": "單于冰嵐"}
{"index": {"_index": "actors", "_id": 6}}
{"name": "賓三春"}
{"index": {"_index": "actors", "_id": 7}}
{"name": "慕容雅云"}
{"index": {"_index": "actors", "_id": 8}}
{"name": "陳子晉"}
{"index": {"_index": "actors", "_id": 9}}
{"name": "黨綺梅"}
{"index": {"_index": "actors", "_id": 10}}
{"name": "慕容鴻暉"}

analyze 過程

在說基于全文本查詢之前扼雏,我們先來說搜索之前的分詞過程坚嗜,這個(gè)過程是是十分重要的

  • 我們以以下一段話來分析一下

Water dropping day by day wears the hardest rock away
[水滴石穿]

# 我們新建一個(gè)搜索
PUT /mine/_doc/1
{
  "name": "Water dropping day by day wears & the hardest rock away"
}

# 簡單查詢一下
GET /mine/_search
{
  "query": {
    "match": {
      "name": "drop"
    }
  }
}
  • 查詢結(jié)果
{
  "took" : 645,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}
  • 看到這個(gè)結(jié)果是不是覺的有些奇怪,drop至少在文檔中有出現(xiàn)诗充,在我們的認(rèn)知中drop跟dropping其實(shí)是一個(gè)詞的不同時(shí)態(tài)苍蔬,為什么搜不出來呢?我們不知道搜索引擎給我們分出了什么詞蝴蜓,那我們使用analyzer的api查看分詞
# 使用analyze api查看分詞結(jié)果
GET /mine/_analyze
{
  "field": "name",
  "text": "Water dropping day by day wears & the hardest rock away"
}
  • 我們看下analyze api作用在name字段上碟绑,輸入text(Water ....),分出來的詞如下:
{
  "tokens" : [
    {
      "token" : "water",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "dropping",
      "start_offset" : 6,
      "end_offset" : 14,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "day",
      "start_offset" : 15,
      "end_offset" : 18,
      "type" : "<ALPHANUM>",
      "position" : 2
    },
    {
      "token" : "by",
      "start_offset" : 19,
      "end_offset" : 21,
      "type" : "<ALPHANUM>",
      "position" : 3
    },
    {
      "token" : "day",
      "start_offset" : 22,
      "end_offset" : 25,
      "type" : "<ALPHANUM>",
      "position" : 4
    },
    {
      "token" : "wears",
      "start_offset" : 26,
      "end_offset" : 31,
      "type" : "<ALPHANUM>",
      "position" : 5
    },
    {
      "token" : "the",
      "start_offset" : 32,
      "end_offset" : 35,
      "type" : "<ALPHANUM>",
      "position" : 6
    },
    {
      "token" : "hardest",
      "start_offset" : 36,
      "end_offset" : 43,
      "type" : "<ALPHANUM>",
      "position" : 7
    },
    {
      "token" : "rock",
      "start_offset" : 44,
      "end_offset" : 48,
      "type" : "<ALPHANUM>",
      "position" : 8
    },
    {
      "token" : "away",
      "start_offset" : 49,
      "end_offset" : 53,
      "type" : "<ALPHANUM>",
      "position" : 9
    }
  ]
}
  • 我們來看下茎匠,輸入drop的關(guān)鍵字的時(shí)候的分詞結(jié)果
GET /mine/_analyze
{
  "field": "name",
  "text": "drop"
}
  • 分詞結(jié)果如下格仲,輸入drop后,分詞器的分詞結(jié)果是drop
{
  "tokens" : [
    {
      "token" : "drop",
      "start_offset" : 0,
      "end_offset" : 4,
      "type" : "<ALPHANUM>",
      "position" : 0
    }
  ]
}
  • 可以看到文檔分詞的結(jié)果是dropping诵冒,而輸入分詞的結(jié)果是drop抓狭,這讓我們看上去是個(gè)相似的詞,但是對(duì)于搜索引擎來說造烁,則需要完全匹配否过,所以用drop來搜索時(shí),搜索不出來結(jié)果惭蟋。

那接下來我們看下analyze的過程

  • 字符過濾->字符處理->分詞過濾(分詞轉(zhuǎn)換)
analyze過程
  • 那我們?nèi)绾问莇rop能搜索出來文檔呢?需要指定分詞器
# 先刪除之前的索引
DELETE /mine

# 創(chuàng)建索引
PUT /mine 
{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "analyzer": "english"
      }
    }
  }
}

# 添加文檔
PUT /mine/_doc/1
{
  "name": "Water dropping day by day wears & the hardest rock away"
}
  • 我們使用analyze api查看一下分詞結(jié)果
GET /mine/_analyze
{
  "field": "name",
  "text": "Water dropping day by day wears & the hardest rock away"
}
  • 分詞結(jié)果
{
  "tokens" : [
    {
      "token" : "water",
      "start_offset" : 0,
      "end_offset" : 5,
      "type" : "<ALPHANUM>",
      "position" : 0
    },
    {
      "token" : "drop",
      "start_offset" : 6,
      "end_offset" : 14,
      "type" : "<ALPHANUM>",
      "position" : 1
    },
    {
      "token" : "dai",
      "start_offset" : 15,
      "end_offset" : 18,
      "type" : "<ALPHANUM>",
      "position" : 2
    },
    {
      "token" : "dai",
      "start_offset" : 22,
      "end_offset" : 25,
      "type" : "<ALPHANUM>",
      "position" : 4
    },
    {
      "token" : "wear",
      "start_offset" : 26,
      "end_offset" : 31,
      "type" : "<ALPHANUM>",
      "position" : 5
    },
    {
      "token" : "hardest",
      "start_offset" : 38,
      "end_offset" : 45,
      "type" : "<ALPHANUM>",
      "position" : 7
    },
    {
      "token" : "rock",
      "start_offset" : 46,
      "end_offset" : 50,
      "type" : "<ALPHANUM>",
      "position" : 8
    },
    {
      "token" : "awai",
      "start_offset" : 51,
      "end_offset" : 55,
      "type" : "<ALPHANUM>",
      "position" : 9
    }
  ]
}

我們看到分詞結(jié)果有些不同苗桂,我們來歸納一下這兩個(gè)分詞器的表現(xiàn)不同的地方

    1. dropping 變?yōu)?drop
    1. by 這個(gè)詞消失了【english分詞器在字符過濾階段將其過濾掉了】
    1. day 這個(gè)詞變?yōu)榱薲ai【english分詞器在分詞過濾階段,進(jìn)行詞干轉(zhuǎn)換告组,比如說復(fù)數(shù)轉(zhuǎn)為單數(shù)(days -> day -> dai)】

現(xiàn)在我們?cè)賵?zhí)行一下query語句就能查詢到了

GET /mine/_search
{
  "query": {
    "match": {
      "name": "drop"
    }
  }
}
  • 查詢結(jié)果
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.2876821,
    "hits" : [
      {
        "_index" : "mine",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.2876821,
        "_source" : {
          "name" : "Water dropping day by day wears & the hardest rock away"
        }
      }
    ]
  }
}

接下來煤伟,我們看看全文本查詢

1.match

執(zhí)行以下查詢,查看執(zhí)行結(jié)果

GET /actors/_search
{
  "query": {
    "match": {
      "name": "慕容浩南"
    }
  }
}
  • 結(jié)果如下:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 4,
      "relation" : "eq"
    },
    "max_score" : 3.002836,
    "hits" : [
      {
        "_index" : "actors",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 3.002836,
        "_source" : {
          "name" : "陳浩南"
        }
      },
      {
        "_index" : "actors",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 3.002836,
        "_source" : {
          "name" : "司徒浩南"
        }
      },
      {
        "_index" : "actors",
        "_type" : "_doc",
        "_id" : "7",
        "_score" : 1.501418,
        "_source" : {
          "name" : "慕容雅云"
        }
      },
      {
        "_index" : "actors",
        "_type" : "_doc",
        "_id" : "10",
        "_score" : 1.501418,
        "_source" : {
          "name" : "慕容鴻暉"
        }
      }
    ]
  }
}
  • 看結(jié)果就能印證我們之前說的木缝,會(huì)對(duì)輸入進(jìn)行分詞便锨,分為三個(gè)詞(慕容,浩我碟,南【可以使用_analyze api進(jìn)行查看】)放案,可以看到結(jié)果是包含慕容或者浩或者南,如果我就要搜慕容浩南呢矫俺?
GET /actors/_search
{
  "query": {
    "match": {
      "name": {
        "query": "慕容浩南",
        "operator": "and"
      }
    }
  }
}
  • 以下為搜索結(jié)果吱殉,遺憾的是并沒有這么個(gè)人在我們的索引中
{
  "took" : 2,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

那都可以配置哪些參數(shù)呢?【不全,沒有印證的沒有寫下來厘托,詳見官網(wǎng)】

  • operator:OR 和 AND友雳。表示對(duì)查詢字符串分詞后,返回的關(guān)鍵字列表铅匹,OR只需一個(gè)滿足及認(rèn)為匹配押赊,而AND則需要全部都匹配,默認(rèn)值為:OR
  • minimum_should_match:最少需要匹配個(gè)數(shù)包斑。在操作類型為OR時(shí)生效流礁,指明分詞后的關(guān)鍵字涕俗,至少minimum_should_match 個(gè)匹配,則命中崇棠。
    以下舉個(gè)例子:我們要查詢關(guān)鍵字”慕容浩南“,其中分詞為”慕容“丸卷,”浩“枕稀,”南“,我們?cè)O(shè)置minimum_should_match為2谜嫉,只要name屬性包含2個(gè)以上關(guān)鍵字[包含2個(gè)]即為匹配
GET /actors/_search
{
  "query": {
    "match": {
      "name": {
        "query": "慕容浩南",
        "operator": "or",
        "minimum_should_match": "2"
      }
    }
  }
}

結(jié)果如下:

{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 3.002836,
    "hits" : [
      {
        "_index" : "actors",
        "_type" : "_doc",
        "_id" : "2",
        "_score" : 3.002836,
        "_source" : {
          "name" : "陳浩南"
        }
      },
      {
        "_index" : "actors",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 3.002836,
        "_source" : {
          "name" : "司徒浩南"
        }
      }
    ]
  }
}
類型 例子 釋義
整型 2 如果分詞的匹配個(gè)數(shù)小于2個(gè)萎坷,則無法匹配到任何條目。
負(fù)整數(shù) -1 負(fù)數(shù)表示最多不允許不匹配的個(gè)數(shù)【也就是需要匹配的個(gè)數(shù)為(總數(shù)-1)】
百分比 75% 百分比沐兰,表示需要匹配的詞占總數(shù)的百分比哆档。
組合類型 2<90% 如果查詢字符串分詞的個(gè)數(shù)小于等于2(前面的整數(shù)),則只要全部匹配則返回住闯,如果分詞的個(gè)數(shù)大于2個(gè)瓜浸,則只要90%的匹配即可。
多組合類型 2<-25% 9<-3 支持多條件表達(dá)式比原,中間用空格分開插佛。該表達(dá)式的意義如下:1、如果分詞的個(gè)數(shù)小于等于2量窘,則必須全部匹配雇寇;如果大于2小于9,則除了25%(注意負(fù)號(hào))之外都需要滿足蚌铜。2锨侯、如果大于9個(gè),則只允許其中3個(gè)不滿足冬殃。
  • analyzer: 設(shè)置分詞器
  • lenient:是否忽略由于數(shù)據(jù)類型不匹配引起的異常囚痴,默認(rèn)為false。例如嘗試用文本查詢字符串查詢數(shù)值字段审葬,默認(rèn)會(huì)拋出錯(cuò)誤渡讼。
  • fuzziness:模糊匹配
  • zero_terms_query:默認(rèn)情況下,如果分詞器會(huì)過濾查詢字句中的停用詞耳璧,可能會(huì)造成查詢字符串分詞后變成空字符串成箫,此時(shí)默認(rèn)的行為是無法匹配到任何文檔,如果想改變?cè)撃J(rèn)情況旨枯,可以設(shè)置zero_terms_query=all,默認(rèn)值為none蹬昌。
  • auto_generate_synonyms_phrase_query:如果為true,則為同義詞自動(dòng)創(chuàng)建短語查詢攀隔。默認(rèn)值為true

2. match phrase

match_phrase檢索時(shí)候皂贩,文檔必須同時(shí)滿足以下兩個(gè)條件栖榨,才能被檢索到:

  • 1)分詞后所有詞項(xiàng)都出現(xiàn)在該字段中;
  • 2)字段中的詞項(xiàng)順序要一致明刷。

對(duì)于匹配了短語"quick brown fox"的文檔婴栽,下面的條件必須為true:

  • quick、brown和fox必須全部出現(xiàn)在某個(gè)字段中辈末。
  • brown的位置必須比quick的位置大1愚争。
  • fox的位置必須比quick的位置大2。

如果以上的任何一個(gè)條件沒有被滿足挤聘,那么文檔就不能被匹配轰枝。

舉個(gè)例子

# 我們搜索”慕容雅云“,注意组去,”慕容雅云“被分詞器分為”慕容“鞍陨,”雅“,”云“
GET /actors/_search
{
  "query": {
    "match_phrase": {
      "name": {
        "query": "慕容雅云"
      }
    }
  }
}
  • 看下結(jié)果
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 5.539568,
    "hits" : [
      {
        "_index" : "actors",
        "_type" : "_doc",
        "_id" : "7",
        "_score" : 5.539568,
        "_source" : {
          "name" : "慕容雅云"
        }
      }
    ]
  }
}
  • 結(jié)果只有一個(gè)从隆,說明分詞后诚撵,需要保證慕容,雅键闺,云都在的文檔可以被篩選出來

再來看下一個(gè)

GET /actors/_search
{
  "query": {
    "match_phrase": {
      "name": {
        "query": "雅云慕容"
      }
    }
  }
}
  • 結(jié)果如下砾脑,啥也沒有,說明艾杏,除了文檔中要同時(shí)包含慕容韧衣,雅,云外购桑,還要保證他們的順序
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 0,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  }
}

但是假如我知道這個(gè)人的名字包含慕容畅铭,雅,云勃蜘,不知道是姓慕容還是姓雅云這該咋整

  • 我們可以使用slop參數(shù)來進(jìn)行調(diào)整硕噩。slop參數(shù)告訴match_phrase查詢?cè)~條能夠相隔多遠(yuǎn)時(shí)仍然將文檔視為匹配。相隔多遠(yuǎn)的意思是缭贡,你需要移動(dòng)一個(gè)詞條多少次來讓查詢和文檔匹配炉擅?
  • 我們先來舉個(gè)例子再來解釋
GET /actors/_search
{
  "query": {
    "match_phrase": {
      "name": {
        "query": "雅云慕容",
        "slop": 3
      }
    }
  }
}
  • 結(jié)果如下:
{
  "took" : 0,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 2.1158507,
    "hits" : [
      {
        "_index" : "actors",
        "_type" : "_doc",
        "_id" : "7",
        "_score" : 2.1158507,
        "_source" : {
          "name" : "慕容雅云"
        }
      }
    ]
  }
}
  • 可以看到有數(shù)據(jù)了,可是為啥呢阳惹?大家可以參考我在借鑒部分的slop的官方文檔谍失,里面用了表格來說明了,挺清楚莹汤,下面我們也來用表格來說明我們這個(gè)快鱼。


    slop
  • 簡要說明一下:我們查詢的是”雅云慕容 “,在文檔中的分詞的順序是”慕容“,”雅“抹竹,”云“线罕,match_phrase查詢時(shí)會(huì)先對(duì)查詢條件進(jìn)行分詞,詞項(xiàng)和順序分為”雅“窃判,”云“钞楼,”慕容“侵歇。第一步徽曲,調(diào)整”慕容“的順序具壮,使它和”雅“并列纱耻;第二步,調(diào)整”雅“的順序搞坝,使它和”云“并列;第三步,調(diào)整”云“窗轩。調(diào)整結(jié)束,索引slop為3座咆。

3. match bool prefix

match_bool_prefix查詢分析其輸入痢艺,并根據(jù)這些關(guān)鍵字構(gòu)造bool查詢。除了最后一個(gè)詞外介陶,每個(gè)詞都在一個(gè)term查詢中使用堤舒。最后一個(gè)詞用于前綴查詢。

  • 舉個(gè)栗子
GET /actors/_search
{
  "query": {
    "match_bool_prefix": {
      "name": "陳浩南"
    }
  }
}
  • 我們上邊的這個(gè)栗子可以重寫為以下語句
GET /actors/_search
{
  "query": {
    "bool" : {
      "should": [
        { "term": { "name": "陳" }},
        { "term": { "name": "浩" }},
        { "prefix": { "name": "南"}}
      ]
    }
  }
}

match_bool_prefix查詢和match_phrase_prefix之間的一個(gè)重要區(qū)別是:
match_phrase_prefix查詢匹配短語哺呜,而match_bool_prefix查詢可以在任何位置匹配短語舌缤。上面的示例match_bool_prefix查詢可以匹配一個(gè)包含"陳浩南"的字段,但是它也可以匹配"浩南陳"某残。它還可以匹配一個(gè)出現(xiàn)在任何位置国撵,可包含"陳"、浩"和以"南"開頭的字段玻墅。當(dāng)然可以使用minimum_should_match來指定匹配的精度介牙。

4.match phrase prefix

返回包含所提供文本的單詞的文檔,其順序與所提供的順序相同澳厢。提供的文本的最后一項(xiàng)作為前綴环础,匹配以該項(xiàng)開頭的任何單詞。

  • 我覺得官方的解釋比較容易懂剩拢,所以直接拿過來了
# 下面的搜索在消息字段中返回包含以quick brown f開頭的短語的文檔线得。
GET /_search
{
    "query": {
        "match_phrase_prefix" : {
            "message" : {
                "query" : "quick brown f"
            }
        }
    }
}

# 這個(gè)搜索會(huì)匹配message為quick brown fox 或者 two quick brown ferrets的文本,但是不會(huì)匹配 fox is quick and brown.

5.multi match

multi_match查詢建立在匹配查詢的基礎(chǔ)上徐伐,支持多字段查詢

GET /tmdb_movies/_search
{
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title", "overview"]
    }
  }
}
  • 使用fields指定在多個(gè)字段上搜索
  • 默認(rèn)是取最大值的得分【即query中分詞后在title字段的打分和query分詞后在overview中的打分取最大值】
放大系數(shù)

如果說我們覺得title字段的分?jǐn)?shù)要比overview字段的分?jǐn)?shù)重要,我們可以指定boot

GET /tmdb_movies/_search
{
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title^3", "overview"]
    }
  }
}

如此一來,在title上的打分就放大了3倍

tie_breaker
GET /tmdb_movies/_search
{
  "explain": true, 
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title^3", "overview"],
      "tie_breaker": 0.3
    }
  }
}

tie_breaker是做什么的呢魏保?我們上邊說到multi_match默認(rèn)是取最大值的評(píng)分熬尺,所以說title放大3倍后評(píng)分比overview要高【我們?nèi)绱思俣ā?br> 那么我們來做一下對(duì)比

我們假定title的打分是0.8,則title^3的打分為2.4
我們假定overview的打分為0.4
我們指定tie_breaker為0.3

搜索屬性 沒有tie_breaker得分 添加tie_breaker得分
["title^3", "overview"] 2.4 2.4 + 0.4 * 0.3

我們可以看到谓罗,tie_breaker的作用是粱哼,文檔的最終得分為文檔的匹配屬性的最大得分+其他屬性的得分*tie_breaker,即綜合考慮所有屬性的得分檩咱,而不是簡單的取最大值

type

multi_match中有很多type

  • best_fileds:默認(rèn)的打分方式揭措,取最高的分?jǐn)?shù)作為文檔的分?jǐn)?shù),與dis_max相同
    -- best_fileds模式
GET /tmdb_movies/_search
{
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title", "overview"]
    }
  }
}

-- dis_max模式[寫法與multi_match不同刻蚯,但是都是取最高分]

GET /tmdb_movies/_search
{
  "query": {
    "dis_max": {
      "queries": [
        {"match": {"title": "basketball with cartoom aliens"}},
        {"match": {"overview": "basketball with cartoom aliens"}}
        ]
    }
  }
}
  • most_fileds:所有文檔字段得分相加
GET /tmdb_movies/_search
{
  "explain": true, 
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title^3", "overview"],
      "type": "most_fields"
    }
  }
}
  • cross_fileds:以分詞為單位計(jì)算總分:搜索詞在不同的fields中的最大值作為這個(gè)詞的打分绊含,然后將每個(gè)詞的打分相加
GET /tmdb_movies/_search
{
  "explain": true, 
  "query": {
    "multi_match": {
      "query": "basketball with cartoom aliens",
      "fields": ["title", "overview"],
      "type": "cross_fields"
    }
  }
}

上面的解釋我們?cè)賮斫忉屢幌拢何覀儾樵僢asketball with cartoom aliens,它的分詞結(jié)果為basketball炊汹,cartoom躬充,alien【為啥with被去掉了呢?因?yàn)槭峭S迷~】讨便。cross_fields的type會(huì)先計(jì)算每個(gè)詞在每個(gè)fields上的打分充甚,我們用表格來表示一下:

- basketball cartoom alien
title 1.0 2.0 1.5
overview 2.0 3.0 1.0

這個(gè)表格表示basketball在title和overview字段上的打分 分別為1.0和2.0,其他字段以此類推霸褒。所以cross_fields這個(gè)type就是取每個(gè)分詞在每個(gè)字段上的最高打分伴找,然后相加,作為文檔的得分废菱。我們這個(gè)例子里技矮,basketball最高得分為2.0,cartoom最高得分為3.0殊轴,alien最高的分為1.5衰倦,所以文檔的最終等分為:2.0 + 3.0 + 1.5 = 6.5

6. query_string

# 索引兩篇文檔
PUT /person/_doc/1
{
  "name": "sun rui kai",
  "know": "java"
}

PUT /person/_doc/2
{
  "name": "gabriella",
  "know": "you and i"
}

查詢

# 在name字段上查詢,必須有sun和rui
GET /person/_search
{
  "query": {
    "query_string": {
      "default_field": "name",
      "query": "sun AND rui"
    }
  }
}

# 可以指定多個(gè)字段
GET /person/_search
{
  "query": {
    "query_string": {
      "fields": ["name", "know"],
      "query": "(sun AND rui) OR gabriella"
    }
  }
}
支持的操作 例子 描述
1 a AND b 必須有a和b
2 a NOT b 必須有a梳凛,必須沒有b
3 a OR b 有a耿币,b兩者其一即可

7. simple_query_string

看名字就知道它跟query_string差不多,那到底有啥區(qū)別呢韧拒?來個(gè)栗子

# 我們?cè)谏厦娴幕A(chǔ)上我們?cè)偌右黄臋n
PUT /person/_doc/3
{
  "name": "sun rui xie",
  "know": "elasticsearch"
}

# 我們用simple_query_string來試試
GET /person/_search
{
  "query": {
    "simple_query_string": {
      "query": "sun AND xie",
      "fields": ["name"]
    }
  }
}
  • 查詢結(jié)果
{
  "took" : 763,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 2,
      "relation" : "eq"
    },
    "max_score" : 1.2990015,
    "hits" : [
      {
        "_index" : "person",
        "_type" : "_doc",
        "_id" : "3",
        "_score" : 1.2990015,
        "_source" : {
          "name" : "sun rui xie",
          "know" : "elasticsearch"
        }
      },
      {
        "_index" : "person",
        "_type" : "_doc",
        "_id" : "1",
        "_score" : 0.4208172,
        "_source" : {
          "name" : "sun rui kai",
          "know" : "java"
        }
      }
    ]
  }
}
  • 可以看到用simple_query_string淹接,我們用AND連接已經(jīng)失效了,這就是兩者的區(qū)別:在simple_query_string中叛溢,query中使用query_string中的連接符會(huì)當(dāng)做普通的普通的字符串來匹配塑悼,那如果我們?nèi)绾沃付ㄟB接符呢?
GET /person/_search
{
  "query": {
    "simple_query_string": {
      "query": "sun xie",
      "fields": ["name"],
      "default_operator": "AND"
    }
  }
}
  • 指定default_operator字段為AND等就可以楷掉,默認(rèn)是OR
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末厢蒜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌斑鸦,老刑警劉巖愕贡,帶你破解...
    沈念sama閱讀 219,188評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異巷屿,居然都是意外死亡固以,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門嘱巾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來憨琳,“玉大人,你說我怎么就攤上這事旬昭「菝” “怎么了?”我有些...
    開封第一講書人閱讀 165,562評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵问拘,是天一觀的道長遍略。 經(jīng)常有香客問我,道長场梆,這世上最難降的妖魔是什么墅冷? 我笑而不...
    開封第一講書人閱讀 58,893評(píng)論 1 295
  • 正文 為了忘掉前任纯路,我火速辦了婚禮或油,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘驰唬。我一直安慰自己顶岸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,917評(píng)論 6 392
  • 文/花漫 我一把揭開白布叫编。 她就那樣靜靜地躺著辖佣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪搓逾。 梳的紋絲不亂的頭發(fā)上卷谈,一...
    開封第一講書人閱讀 51,708評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音霞篡,去河邊找鬼世蔗。 笑死,一個(gè)胖子當(dāng)著我的面吹牛朗兵,可吹牛的內(nèi)容都是我干的污淋。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼余掖,長吁一口氣:“原來是場噩夢(mèng)啊……” “哼寸爆!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,342評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤赁豆,失蹤者是張志新(化名)和其女友劉穎仅醇,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體魔种,經(jīng)...
    沈念sama閱讀 45,801評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡着憨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,976評(píng)論 3 337
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了务嫡。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片甲抖。...
    茶點(diǎn)故事閱讀 40,115評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖心铃,靈堂內(nèi)的尸體忽然破棺而出准谚,到底是詐尸還是另有隱情,我是刑警寧澤去扣,帶...
    沈念sama閱讀 35,804評(píng)論 5 346
  • 正文 年R本政府宣布柱衔,位于F島的核電站,受9級(jí)特大地震影響愉棱,放射性物質(zhì)發(fā)生泄漏唆铐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,458評(píng)論 3 331
  • 文/蒙蒙 一奔滑、第九天 我趴在偏房一處隱蔽的房頂上張望艾岂。 院中可真熱鬧,春花似錦朋其、人聲如沸王浴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽氓辣。三九已至,卻和暖如春袱蚓,著一層夾襖步出監(jiān)牢的瞬間钞啸,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評(píng)論 1 272
  • 我被黑心中介騙來泰國打工喇潘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留体斩,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,365評(píng)論 3 373
  • 正文 我出身青樓响蓉,卻偏偏與公主長得像硕勿,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子枫甲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,055評(píng)論 2 355