前言
有的時候,我們對查詢有一定的混淆,尤其是Term查詢和Full Text查詢。樓主希望通過這篇文章闡述清楚這兩者的區別。
Term查詢
在前面章節我們已經知道了Term這個單詞的含義,即:表達語意的最小單元,也叫詞項。Term查詢主要包括:Term Query、Range Query、Exists Query、Prefix Query、Wildcard Query。
Term查詢的特點在于,查詢本身對輸入不做分詞。Elasticsearch會將輸入作為一個整體,在倒排索引中查找準確的詞項,然后對查詢結果進行相關度算分。另外,我們還可以通過Constant Score,將查詢轉換成一個Filtering,從而避免算分,且利用緩存來提高性能。
下面,我們舉一個例子。
先創建一個products的索引。
DELETE products
PUT products
{
"settings": {
"number_of_shards": 1
}
}
通過_bulk的api來插入3條記錄
POST /products/_bulk
{ "index": { "_id": 1 }}
{ "productID" : "XHDK-A-1293-#fJ3","desc":"iPhone" }
{ "index": { "_id": 2 }}
{ "productID" : "KDKE-B-9947-#kL5","desc":"iPad" }
{ "index": { "_id": 3 }}
{ "productID" : "JODL-X-1937-#pV7","desc":"MBP" }
對desc字段做term查詢,且iPhone
的字母P為大寫。我們發現未查詢到任何結果。
POST /products/_search
{
"query": {
"term": {
"desc": {
"value": "iPhone"
//"value":"iphone"
}
}
}
}
我們在對desc字段做term查詢,只是這一次將iphone
的字母p更改為小寫。我們發現已經能查詢出第一條結果了。通過這種方式,我們其實已經驗證了我們的定義。
POST /products/_search
{
"query": {
"term": {
"desc": {
//"value": "iPhone"
"value":"iphone"
}
}
}
}
另外,如果我們想對desc做精準匹配,有沒有辦法呢?也是有的,就是通過desc的子字段keyword來查詢即可。我們發現,keyword做term查詢的時候,如果傳入值為iPhone,那么可以查詢出結果。如果傳入值為iphone,那么查詢不出結果。
POST /products/_search
{
"query": {
"term": {
"desc.keyword": {
"value": "iPhone"
//"value":"iphone"
}
}
}
}
我們再來通過productID來查詢一下。
POST /products/_search
{
"query": {
"term": {
"productID": {
//"value": "XHDK-A-1293-#fJ3"
"value": "xhdk-a-1293-#fJ3"
}
}
}
}
我們發現,不管值為XHDK-A-1293-#fJ3
,還是轉換為小寫的xhdk-a-1293-#fJ3
,都查詢不出結果。這又是為什么呢?原因在于term查詢不會對輸入進行分詞處理。我們通過_analyze
來分析看看。
POST /_analyze
{
"analyzer": "standard",
"text": "XHDK-A-1293-#fJ3"
}
我們可以通過下面的方式查詢到結果。
POST /products/_search
{
"query": {
"term": {
"productID": {
"value": "xhdk"
}
}
}
}
POST /products/_search
{
"query": {
"term": {
"productID.keyword": {
"value": "XHDK-A-1293-#fJ3"
}
}
}
}
Full Text查詢
包括:Match Query / Match Phrase Query / Query String Query。
其特點如下:
- 索引和搜索時都會進行分詞,查詢字符串先傳遞到一個合適的分詞器,然后生成一個供查詢的詞項列表
- 查詢的時候,Elasticsearch會先對輸入的查詢進行分詞,然后對每個詞項逐個進行底層的查詢,最終將結果進行合并匯總。同時,Elasticsearch會對每個文檔生成一個相關性分數。例如查詢“Mr zhang”,會查到包括 Mr 或者 zhang 的所有結果。
DELETE groups
PUT groups
{
"mappings": {
"properties": {
"names":{
"type": "text",
"position_increment_gap": 0
}
}
}
}
GET groups/_mapping
POST groups/_doc
{
"names": [ "John Water", "Water Smith"]
}
POST groups/_search
{
"query": {
"match_phrase": {
"names": {
"query": "Water Water",
"slop": 100
}
}
}
}
POST groups/_search
{
"query": {
"match_phrase": {
"names": "Water Smith"
}
}
}
參考鏈接
- https://www.elastic.co/guide/en/elasticsearch/reference/current/term-level-queries.html
- https://www.elastic.co/guide/en/elasticsearch/reference/current/full-text-queries.html
總結
通過本文,我們了解了term查詢和Full Text查詢的區別及聯系。