国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

ElasticSearch高級查詢語法

這篇具有很好參考價值的文章主要介紹了ElasticSearch高級查詢語法。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

1. ES倒排索引

當(dāng)數(shù)據(jù)寫入ES時,數(shù)據(jù)將會通過“分詞”被切分為不同的term,ES將term與其對應(yīng)的文檔列表建立一種映射關(guān)系,這種結(jié)構(gòu)就是倒排索引。如下圖所示:

ElasticSearch高級查詢語法,elasticsearch,大數(shù)據(jù)

為了進(jìn)一步提升索引的效率,ES在term的基礎(chǔ)上利用term的前綴或者后綴構(gòu)建了term index,用于對term本身進(jìn)行索引,ES實(shí)際的索引結(jié)構(gòu)如下圖所示:

ElasticSearch高級查詢語法,elasticsearch,大數(shù)據(jù)

這樣當(dāng)我們?nèi)ニ阉髂硞€關(guān)鍵詞時,ES 首先根據(jù)它的前綴或者后綴迅速縮小關(guān)鍵詞的在term dictionary中的范圍,大大減少了磁盤IO的次數(shù)。

  • 單詞詞典(Term Dictionary) :記錄所有文檔的單詞,記錄單詞到倒排列表的關(guān)聯(lián)關(guān)系;
  • 倒排列表(Posting List)-記錄了單詞對應(yīng)的文檔,由倒排索引項(xiàng)組成;
  • 倒排索引項(xiàng)(Posting):
    • 文檔ID
    • 詞頻TF–該單詞在文檔中出現(xiàn)的次數(shù),用于相關(guān)性評分;
    • 位置(Position)-單詞在文檔中分詞的位置。用于短語搜索(match phrase query)
    • 偏移(Offset)-記錄單詞的開始結(jié)束位置,實(shí)現(xiàn)高亮顯示。

ElasticSearch高級查詢語法,elasticsearch,大數(shù)據(jù)

Elasticsearch的JSON文檔中的每個字段,都有自己的倒排索引。

可以指定對某些字段不做索引:

  • 優(yōu)點(diǎn)︰節(jié)省存儲空間
  • 缺點(diǎn): 字段無法被搜索

2. 文檔映射Mapping

Mapping類似數(shù)據(jù)庫中的Schema的定義,作用如下:

  • 定義索引中的字段的名稱
  • 定義字段的數(shù)據(jù)類型,例如字符串,數(shù)字,布爾等;
  • 字段,倒排索引的相關(guān)配置(Analyzer)。

ES中Mapping映射可以分為動態(tài)映射和靜態(tài)映射:

  • 動態(tài)映射:在關(guān)系數(shù)據(jù)庫中,需要事先創(chuàng)建數(shù)據(jù)庫,然后在該數(shù)據(jù)庫下創(chuàng)建數(shù)據(jù)表,并創(chuàng)建表字段、類型、長度、主鍵等,最后才能基于表插入數(shù)據(jù)。而Elasticsearch中不需要定義Mapping映射(即關(guān)系型數(shù)據(jù)庫的表、字段等),在文檔寫入Elasticsearch時,會根據(jù)文檔字段自動識別類型,這種機(jī)制稱之為動態(tài)映射。
  • 靜態(tài)映射:靜態(tài)映射是在Elasticsearch中也可以事先定義好映射,包含文檔的各字段類型、分詞器等,這種方式稱之為靜態(tài)映射。

動態(tài)映射(Dynamic Mapping)的機(jī)制,使得我們無需手動定義Mappings,Elasticsearch會自動根據(jù)文檔信息,推算出字段的類型。但是有時候會推算的不對,例如地理位置信息。當(dāng)類型如果設(shè)置不對時,會導(dǎo)致一些功能無法正常運(yùn)行,例如Range查詢。

  • Dynamic Mapping類型自動識別:

ElasticSearch高級查詢語法,elasticsearch,大數(shù)據(jù)

??示例

#刪除原索引
DELETE /user
#創(chuàng)建文檔(ES根據(jù)數(shù)據(jù)類型, 會自動創(chuàng)建映射)
PUT /user/_doc/1
{
  "name":"magic",
  "age":32,
  "address":"哈爾濱中央大街"
}
#獲取文檔映射
GET /user/_mapping

ElasticSearch高級查詢語法,elasticsearch,大數(shù)據(jù)

思考:能否后期更改Mapping的字段類型?

兩方面考慮:

  • 新增加字段
    • dynamic設(shè)為true時,一旦有新增字段的文檔寫入,Mapping也同時被更新;
    • dynamic設(shè)為false,Mapping不會被更新,新增字段的數(shù)據(jù)無法被索引,但是信息會出現(xiàn)在_source中;
    • dynamic設(shè)置成strict(嚴(yán)格控制策略),文檔寫入失敗,拋出異常。

true

false

strict

文檔可索引

yes

yes

no

字段可索引

yes

no

no

Mapping被更新

yes

no

no

  • 對已有字段,一旦已經(jīng)有數(shù)據(jù)寫入,就不再支持修改字段定義。
    • Lucene實(shí)現(xiàn)的倒排索引,一旦生成后,就不允許修改;
    • 如果希望改變字段類型,可以利用 reindex API,重建索引。

原因:

  • 如果修改了字段的數(shù)據(jù)類型,會導(dǎo)致已被索引的數(shù)據(jù)無法被搜索;
  • 但是如果是增加新的字段,就不會有這樣的影響。

??測試

PUT /user
{
  "mappings": {
    "dynamic": "strict",
    "properties": {
      "name": {
        "type": "text"
      },
      "address": {
        "type": "object",
        "dynamic": "true"
      }
    }
  }
}
# 插入文檔報錯,原因?yàn)閍ge為新增字段,會拋出異常
PUT /user/_doc/1
{
  "name":"fox",
  "age":32,
  "address":{
    "province":"湖南",
    "city":"長沙"
  }
}

dynamic設(shè)置成strict,新增age字段導(dǎo)致文檔插入失敗。

ElasticSearch高級查詢語法,elasticsearch,大數(shù)據(jù)

修改dynamic后再次插入文檔成功

#修改daynamic
PUT /user/_mapping
{
  "dynamic":true
}

ElasticSearch高級查詢語法,elasticsearch,大數(shù)據(jù)

對已有字段的mapping修改

  1. 如果要推倒現(xiàn)有的映射,你得重新建立一個靜態(tài)索引;
  2. 然后把之前索引里的數(shù)據(jù)導(dǎo)入到新的索引里
  3. 刪除原創(chuàng)建的索引
  4. 為新索引起個別名,為原索引名。

2.1 常用Mapping參數(shù)配置

2.1.1 index

index,控制當(dāng)前字段是否被索引,默認(rèn)為true;如果設(shè)置為false,該字段不可被搜索。

DELETE /user
PUT /user
{
  "mappings" : {
      "properties" : {
        "address" : {
          "type" : "text",
          "index": false
        },
        "age" : {
          "type" : "long"
        },
        "name" : {
          "type" : "text"
        }
      }
    }
}

PUT /user/_doc/1
{
  "name":"magic",
  "address":"哈爾濱中央大街",
  "age":30
}

GET /user

GET /user/_search
{
  "query": {
    "match": {
      "address": "廣州"
    }
  }
}

ElasticSearch高級查詢語法,elasticsearch,大數(shù)據(jù)

2.1.2 index options

index options有四種不同的基本配置,控制倒排索引記錄的內(nèi)容:

  • docs : 記錄doc id
  • freqs:記錄doc id 和term frequencies(詞頻)
  • positions: 記錄doc id / term frequencies / term position
  • offsets: doc id / term frequencies / term posistion / character offsets

text類型默認(rèn)記錄postions,其他默認(rèn)為 docs;記錄內(nèi)容越多,占用存儲空間越大。

DELETE /user
PUT /user
{
  "mappings" : {
      "properties" : {
        "address" : {
          "type" : "text",
          "index_options": "offsets"
        },
        "age" : {
          "type" : "long"
        },
        "name" : {
          "type" : "text"
        }
      }
    }
}

2.1.3 null_value

需要對Null值進(jìn)行搜索,只有keyword類型支持設(shè)計Null_Value。

DELETE /user
PUT /user
{
  "mappings" : {
      "properties" : {
        "address" : {
          "type" : "keyword",
          "null_value": "NULL"
        },
        "age" : {
          "type" : "long"
        },
        "name" : {
          "type" : "text"
        }
      }
    }
}

PUT /user/_doc/1
{
  "name":"fox",
  "age":32,
  "address":null
}

GET /user/_search
{
  "query": {
    "match": {
      "address": "NULL"
    }
  }
}

ElasticSearch高級查詢語法,elasticsearch,大數(shù)據(jù)

2.1.4 copy_to

????????將字段的數(shù)值拷貝到目標(biāo)字段,滿足一些特定的搜索需求;copy_to的目標(biāo)字段不出現(xiàn)在_source中。

# 設(shè)置copy_to
DELETE /address
PUT /address
{
  "mappings" : {
      "properties" : {
        "province" : {
          "type" : "keyword",
          "copy_to": "full_address"
        },
        "city" : {
          "type" : "text",
          "copy_to": "full_address"
        }
      }
    },
    "settings" : {
        "index" : {
            "analysis.analyzer.default.type": "ik_max_word"
        }
    }
}

PUT /address/_bulk
{ "index": { "_id": "1"} }
{"province": "湖南","city": "長沙"}
{ "index": { "_id": "2"} }
{"province": "湖南","city": "常德"}
{ "index": { "_id": "3"} }
{"province": "廣東","city": "廣州"}
{ "index": { "_id": "4"} }
{"province": "湖南","city": "邵陽"}

GET /address/_search
{
  "query": {
    "match": {
      "full_address": {
        "query": "湖南常德",
        "operator": "and"
      }
    }
  }
}

2.2 Index Template

Index Templates可以幫助你設(shè)定Mappings和Settings,并按照一定的規(guī)則,自動匹配到新創(chuàng)建的索引之上。

  • 模版僅在一個索引被新創(chuàng)建時,才會產(chǎn)生作用。修改模版不會影響已創(chuàng)建的索引;
  • 你可以設(shè)定多個索引模版,這些設(shè)置會被“merge”在一起;
  • 你可以指定“order”的數(shù)值,控制“merging”的過程。

2.2.1 模板的創(chuàng)建

PUT /_template/template_default
{
  "index_patterns": ["*"],  
  "order": 0,
  "version": 1,
  "settings": {
    "number_of_shards": 1,
    "number_of_replicas": 1
  }
}

PUT /_template/template_test
{
  "index_patterns": ["test*"], #匹配index的
  "order": 1,
  "settings": {
    "number_of_shards": 2,
    "number_of_replicas": 1
  },
  "mappings": {
    "date_detection": false,
    "numeric_detection": true
  }
}

2.2.2 模板的工作方式

當(dāng)一個索引被新創(chuàng)建時,配置信息的默認(rèn)規(guī)則:

  • 應(yīng)用Elasticsearch默認(rèn)的settings和mappings
  • 應(yīng)用order數(shù)值低的lndex Template中的設(shè)定
  • 應(yīng)用order高的Index Template中的設(shè)定,之前的設(shè)定會被覆蓋;
  • 應(yīng)用創(chuàng)建索引時,用戶所指定的Settings和Mappings,并覆蓋之前模版中的設(shè)定。

2.3 Dynamic Template

Dynamic Tempate定義在某個索引的Mapping中。粒度更細(xì),可以根據(jù)字段類型設(shè)置模板。

#Dynaminc Mapping 根據(jù)類型和字段名
DELETE my_index
PUT my_index/_doc/1
{
  "firstName":"Ruan",
  "isVIP":"true"
}

GET my_index/_mapping
DELETE my_index
PUT my_index
{
  "mappings": {
    "dynamic_templates": [
      { 
        "strings_as_boolean": {
          "match_mapping_type":   "string",
          "match":"is*",
          "mapping": {
            "type": "boolean"
          }
        }
      },
      {
        "strings_as_keywords": {
          "match_mapping_type":   "string",
          "mapping": {
            "type": "keyword"
          }
        }
      }
    ]
  }
}

#結(jié)合路徑
PUT /my_test_index
{
  "mappings": {
    "dynamic_templates": [
      {
        "full_name":{
          "path_match": "name.*",
          "path_unmatch": "*.middle",
          "mapping":{
            "type": "text",
            "copy_to": "full_name"
          }
        }
      }
    ]
  }
}

PUT /my_test_index/_doc/1
{
  "name":{
    "first": "John",
    "middle": "Winston",
    "last": "Lennon"
  }
}

GET /my_test_index/_search
{
  "query": {
    "match": {
      "full_name": "John"
    }
  }
}

3. ES高級查詢Query DSL

????????ES中提供了一種強(qiáng)大的檢索數(shù)據(jù)方式,這種檢索方式稱之為Query DSL(Domain Specified Language),Query DSL是利用Rest API傳遞JSON格式的請求體(RequestBody)數(shù)據(jù)與ES進(jìn)行交互,這種方式的豐富查詢語法讓ES檢索變得更強(qiáng)大,更簡潔。

Query DSL | Elasticsearch Guide [7.17] | Elastic

??語法

GET /es_db/_doc/_search {json請求體數(shù)據(jù)}
#可以簡化為下面寫法
GET /es_db/_search {json請求體數(shù)據(jù)}

??示例

#無條件查詢,默認(rèn)返回10條數(shù)據(jù)
GET /es_db/_search
{
    "query":{
        "match_all":{}
    }
}

ElasticSearch高級查詢語法,elasticsearch,大數(shù)據(jù)

3.1 查詢所有match_all

????????使用match_all,默認(rèn)只會返回10條數(shù)據(jù)(_search查詢默認(rèn)采用的是分頁查詢,每頁記錄數(shù)size的默認(rèn)值為10);如果想顯示更多數(shù)據(jù),指定size。

GET /es_db/_search
等同于
GET /es_db/_search
{
    "query":{
        "match_all":{}
    }
}
#在查詢中過濾
#不查看源數(shù)據(jù),僅查看元字段
{
  "_source": false,
  "query": {
    ...
  } 
}
#只看以obj.開頭的字段
{
  "_source": "obj.*",
  "query": {
    ...
  } 
}

3.1.1 返回指定條數(shù)size

????????使用size,指定查詢結(jié)果中返回指定條數(shù)(默認(rèn)返回值10條)。

GET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "size": 100
}

思考: size可以無限增加嗎?

  • 測試
GET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "size": 20000
}
  • 出現(xiàn)異常

ElasticSearch高級查詢語法,elasticsearch,大數(shù)據(jù)

異常原因:

  1. 查詢結(jié)果的窗口太大,from + size的結(jié)果必須小于或等于10000,而當(dāng)前查詢結(jié)果的窗口為20000。
  2. 可以采用scroll?api更高效的請求大量數(shù)據(jù)集。
  3. 查詢結(jié)果的窗口的限制可以通過參數(shù)index.max_result_window進(jìn)行設(shè)置。
PUT /es_db/_settings
{ 
  "index.max_result_window" :"20000"
}
#修改現(xiàn)有所有的索引,但新增的索引,還是默認(rèn)的10000。
PUT /_all/_settings
{ 
  "index.max_result_window" :"20000"
}

#查看所有索引中的index.max_result_window值
GET /_all/_settings/index.max_result_window

注意

????????參數(shù)index.max_result_window主要用來限制單次查詢滿足查詢條件的結(jié)果窗口的大小,窗口大小由from + size共同決定。不能簡單理解成查詢返回給調(diào)用方的數(shù)據(jù)量。這樣做主要是為了限制內(nèi)存的消耗。

????????比如:from為1000000,size為10,邏輯意義是從滿足條件的數(shù)據(jù)中取1000000到(1000000 + 10)的記錄。這時ES一定要先將(1000000 + 10)的記錄(即result_window)加載到內(nèi)存中,再進(jìn)行分頁取值的操作。盡管最后我們只取了10條數(shù)據(jù)返回給客戶端,但ES進(jìn)程執(zhí)行查詢操作的過程中確需要將(1000000 + 10)的記錄都加載到內(nèi)存中,可想而知對內(nèi)存的消耗有多大。這也是ES中不推薦采用(from + size)方式進(jìn)行深度分頁的原因。

????????同理,from為0,size為1000000時,ES進(jìn)程執(zhí)行查詢操作的過程中確需要將1000000 條記錄都加載到內(nèi)存中再返回給調(diào)用方,也會對ES內(nèi)存造成很大壓力。

3.1.2 分頁查詢form

????????from 關(guān)鍵字,用來指定起始返回位置,和size關(guān)鍵字連用可實(shí)現(xiàn)分頁效果。

ET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "size": 5,
  "from": 0
}

3.1.3 指定字段排序sort

????????注意:會讓得分失效

GET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": "desc"
    }
  ]
}

#排序,分頁
GET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "sort": [
    {
      "age": "desc"
    }
  ],
  "from": 10,
  "size": 5
}

3.1.4?返回指定字段_source

????????_source 關(guān)鍵字,是一個數(shù)組,在這個數(shù)組中指定展示哪些字段。

GET /es_db/_search
{
  "query": {
    "match_all": {}
  },
  "_source": ["name","address"]
}

3.2 全文檢索

????????全文檢索查詢(Full Text Queries)和術(shù)語級別查詢(Term-Level Queries)是 Elasticsearch 中搜索和檢索數(shù)據(jù)的兩種不同方法。全文檢索查詢指在基于相關(guān)性搜索和匹配文本數(shù)據(jù)。這些查詢會對輸入的文本進(jìn)行分析,將其拆分為詞項(xiàng)(單個單詞),并執(zhí)行諸如分詞、詞干處理和標(biāo)準(zhǔn)化等操作。Elasticsearch 中的一些全文檢索查詢示例包括 match、match_phrase 和 multi_match 查詢。全文檢索的關(guān)鍵特點(diǎn):

  • 對輸入的文本進(jìn)行分析,并根據(jù)分析后的詞項(xiàng)進(jìn)行搜索和匹配。全文檢索查詢會對輸入的文本進(jìn)行分析,將其拆分為詞項(xiàng),并基于這些詞項(xiàng)進(jìn)行搜索和匹配操作。
  • 以相關(guān)性為基礎(chǔ)進(jìn)行搜索和匹配。全文檢索查詢使用相關(guān)性算法來確定文檔與查詢的匹配程度,并按照相關(guān)性進(jìn)行排序。相關(guān)性可以基于詞項(xiàng)的頻率、權(quán)重和其他因素來計算。
  • 全文檢索查詢適用于包含自由文本數(shù)據(jù)的字段,例如文檔的內(nèi)容、文章的正文或產(chǎn)品描述等。

3.2.1 match query

????????match在匹配時會對所查找的關(guān)鍵詞進(jìn)行分詞,然后按分詞匹配查找,match支持以下參數(shù):

  • query : 指定匹配的值
    • operator : 匹配條件類型
      • and:條件分詞后都要匹配
      • or:條件分詞后有一個匹配即可(默認(rèn))
  • minmum_should_match:最低匹配度,即條件在倒排索引中最低的匹配度。
# 模糊匹配 分詞后"or"的效果
GET /es_db/_search
{
  "query": {
    "match": {
      "address": "廣州白云山公園"
    }
  }
}

# 分詞后"and"的效果
GET /es_db/_search
{
  "query": {
    "match": {
      "address":{
        "query": "廣州白云山公園",
        "operator": "and"
      }
    }
  }
}

????????在match中的應(yīng)用: 當(dāng)operator參數(shù)設(shè)置為or時,minnum_should_match參數(shù)用來控制匹配的分詞的最少數(shù)量。

# 最少匹配廣州,公園兩個詞
GET /es_db/_search
{
  "query": {
    "match": {
      "address": {
        "query": "廣州公園",
        "minimum_should_match": 2
      }
    }
  }
}

3.2.2 match_phrase

????????短語查詢,match_phrase查詢分析文本并根據(jù)分析的文本創(chuàng)建一個短語查詢。match_phrase會將檢索關(guān)鍵詞分詞。match_phrase的分詞結(jié)果必須在被檢索字段的分詞中都包含,而且順序必須相同,而且默認(rèn)必須都是連續(xù)的。

GET /es_db/_search
{
  "query": {
    "match_phrase": {
      "address": "廣州白云山"
    }
  }
}
GET /es_db/_search
{
  "query": {
    "match_phrase": {
      "address": "廣州白云"
    }
  }
}
  • 思考:為什么查詢廣州白云山有數(shù)據(jù),廣州白云沒有數(shù)據(jù)?

ElasticSearch高級查詢語法,elasticsearch,大數(shù)據(jù)

  • 分析原因:

????????先查看廣州白云山公園分詞結(jié)果,可以知道廣州和白云不是相鄰的詞條,中間會隔一個白云山,而match_phrase匹配的是相鄰的詞條,所以查詢廣州白云山有結(jié)果,但查詢廣州白云沒有結(jié)果。

POST _analyze
{
    "analyzer":"ik_max_word",
    "text":"廣州白云山"
}
#結(jié)果
{
  "tokens" : [
    {
      "token" : "廣州",
      "start_offset" : 0,
      "end_offset" : 2,
      "type" : "CN_WORD",
      "position" : 0
    },
    {
      "token" : "白云山",
      "start_offset" : 2,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 1
    },
    {
      "token" : "白云",
      "start_offset" : 2,
      "end_offset" : 4,
      "type" : "CN_WORD",
      "position" : 2
    },
    {
      "token" : "云山",
      "start_offset" : 3,
      "end_offset" : 5,
      "type" : "CN_WORD",
      "position" : 3
    }
  ]
}

????????如何解決詞條間隔的問題?可以借助slop參數(shù),slop參數(shù)告訴match_phrase查詢詞條能夠相隔多遠(yuǎn)時仍然將文檔視為匹配。

#廣州云山分詞后相隔為2,可以匹配到結(jié)果
GET /es_db/_search
{
  "query": {
    "match_phrase": {
      "address": {
        "query": "廣州云山",
        "slop": 2
      } 
    }
  }
}

3.2.3 multi_match

????????多字段查詢,可以根據(jù)字段類型,決定是否使用分詞查詢,得分最高的在前面。

GET /es_db/_search
{
  "query": {
    "multi_match": { #地址和名稱中如果匹配到都能查詢到
      "query": "長沙張龍",
      "fields": [
        "address",
        "name"
      ]
    }
  }
}

????????注意:字段類型分詞,將查詢條件分詞之后進(jìn)行查詢,如果該字段不分詞就會將查詢條件作為整體進(jìn)行查詢。

3.2.4 query_string

????????允許我們在單個查詢字符串中指定AND | OR | NOT條件,同時也和 multi_match query 一樣,支持多字段搜索。和match類似,但是match需要指定字段名,query_string是在所有字段中搜索,范圍更廣泛。

????????注意:查詢字段分詞就將查詢條件分詞查詢,查詢字段不分詞將查詢條件不分詞查詢。

3.2.4.1 未指定字段查詢
GET /es_db/_search
{
  "query": {
    "query_string": {
      "query": "張三 OR 橘子洲"
    }
  }
}
3.2.4.2 指定單個字段查詢
#Query String
GET /es_db/_search
{
  "query": {
    "query_string": {
      "default_field": "address",
      "query": "白云山 OR 橘子洲"
    }
  }
}
3.2.4.3 指定多個字段查詢
GET /es_db/_search
{
  "query": {
    "query_string": {
      "fields": ["name","address"],
      "query": "張三 OR (廣州 AND 王五)"
    }
  }
}

3.2.5 simple_query_string

????????類似query_string,但是會忽略錯誤的語法,同時只支持部分查詢語法,不支持AND OR NOT,會當(dāng)作字符串處理。支持部分邏輯:

  • + 替代AND
  • | 替代OR
  • - 替代NOT
#simple_query_string 默認(rèn)的operator是OR
GET /es_db/_search
{
  "query": {
    "simple_query_string": {
      "fields": ["name","address"],
      "query": "廣州公園",
      "default_operator": "AND"
    }
  }
}

GET /es_db/_search
{
  "query": {
    "simple_query_string": {
      "fields": ["name","address"],
      "query": "廣州 + 公園"
    }
  }
}

3.3 術(shù)語級別查詢

????????術(shù)語級別查詢(Term-Level Queries)指的是搜索內(nèi)容不經(jīng)過文本分析直接用于文本匹配,這個過程類似于數(shù)據(jù)庫的SQL查詢,搜索的對象大多是索引的非text類型字段。Elasticsearch 中的一些術(shù)語級別查詢示例包括 term、terms 和 range 查詢。

3.3.1 關(guān)鍵詞查詢Term

????????Term用來使用關(guān)鍵詞查詢(精確匹配),還可以用來查詢沒有被進(jìn)行分詞的數(shù)據(jù)類型。Term是表達(dá)語意的最小單位,搜索和利用統(tǒng)計語言模型進(jìn)行自然語言處理都需要處理Term。match在匹配時會對所查找的關(guān)鍵詞進(jìn)行分詞,然后按分詞匹配查找,而term會直接對關(guān)鍵詞進(jìn)行查找。一般模糊查找的時候,多用match,而精確查找時可以使用term。

  • ES中默認(rèn)使用分詞器為標(biāo)準(zhǔn)分詞器(StandardAnalyzer),標(biāo)準(zhǔn)分詞器對于英文單詞分詞,對于中文單字分詞。
  • 在ES的Mapping Type 中 keyword、date、integer、long、double、boolean這些類型不分詞,只有text類型分詞。

????????注意:最好不要在term查詢的字段中使用text字段,因?yàn)閠ext字段會被分詞,這樣做既沒有意義,還很有可能什么也查不到。

# 對bool,日期,數(shù)字,結(jié)構(gòu)化的文本可以利用term做精確匹配
# term 精確匹配
GET /es_db/_search
{
  "query": {
    "term": {
      "age": {
        "value": 28
      }
    }
  }
}

# 思考: 查詢廣州白云是否有數(shù)據(jù),為什么?
GET /es_db/_search
{
  "query":{
    "term": {
      "address": {
        "value": "廣州白云"
      }
    }
  }
}

# 采用term精確查詢, 查詢字段映射類型為keyword
GET /es_db/_search
{
  "query":{
    "term": {
      "address.keyword": {
        "value": "廣州白云山公園"
      }
    }
  }
}

????????在ES中,Term查詢時對輸入不做分詞。會將輸入作為一個整體,在倒排索引中查找準(zhǔn)確的詞項(xiàng),并且使用相關(guān)度算分公式為每個包含該詞項(xiàng)的文檔進(jìn)行相關(guān)度算分。

PUT /product/_bulk
{"index":{"_id":1}}
{"productId":"xxx123","productName":"iPhone"}
{"index":{"_id":2}}
{"productId":"xxx111","productName":"iPad"}

# 思考: 查詢iPhone可以查到數(shù)據(jù)嗎? 答:查不到,因?yàn)?iPhone"會被小寫保存。
GET /product/_search
{
  "query":{
    "term": {
      "productName": {
        "value": "iPhone"
      }
    }
  }
}

GET /product/_analyze
{
  "analyzer":"standard",
  "text":"iPhone"
}

# 對于英文,可以考慮建立索引時忽略大小寫
PUT /product
{
  "settings": {
    "analysis": {
      "normalizer": {
        "es_normalizer": {
          "filter": [
            "lowercase",
            "asciifolding"
          ],
          "type": "custom"
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "productId": {
        "type": "text"
      },
      "productName": {
        "type": "keyword",
        "normalizer": "es_normalizer",
        "index": "true"
      }
    }
  }
}

????????使用Term查詢時,可以通過Constant Score將查詢轉(zhuǎn)換成一個Filtering,避免算分,并利用緩存,提高性能。

  • 將Query轉(zhuǎn)成Filter,忽略TF-IDF計算,避免相關(guān)性算分的開銷;
  • Filter可以有效利用緩存
GET /es_db/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "address.keyword": "廣州白云山公園"
        }
      }
    }
  }
}

????????term處理多值字段時,term查詢是包含,不是等于。

POST /employee/_bulk
{"index":{"_id":1}}
{"name":"小明","interest":["跑步","籃球"]}
{"index":{"_id":2}}
{"name":"小紅","interest":["跳舞","畫畫"]}
{"index":{"_id":3}}
{"name":"小麗","interest":["跳舞","唱歌","跑步"]}

POST /employee/_search
{
  "query": {
    "term": {
      "interest.keyword": {
        "value": "跑步"
      }
    }
  }
}

3.3.2 多術(shù)語查詢Terms

????????Terms用于在指定字段上匹配多個詞項(xiàng)(terms)。它會精確匹配指定字段中包含的任何一個詞項(xiàng)。

POST /es_db/_search
{
  "query": {
    "terms": {
      "remark.keyword": ["java assistant", "java architect"]
    }
  }
}

3.3.3 exists query

????????在Elasticsearch中可以使用exists進(jìn)行查詢,以判斷文檔中是否存在對應(yīng)的字段。

#查詢索引庫中存在remarks字段的文檔數(shù)據(jù)
GET /es_db/_search
{
  "query": {
    "exists": 
    {
      "field": "remark"
    }
  }
}

3.3.4 多id查詢ids

????????ids 關(guān)鍵字?: 值為數(shù)組類型,用來根據(jù)一組id獲取多個對應(yīng)的文檔。

GET /es_db/_search
{
  "query": {
    "ids": {
      "values": [1,2]
    }
  }
}

3.3.5 范圍查詢range

  • range:范圍關(guān)鍵字
  • gte 大于等于
  • lte ?小于等于
  • gt 大于
  • lt 小于
  • now 當(dāng)前時間
POST /es_db/_search
{
  "query": {
    "range": {
      "age": {
        "gte": 25,
        "lte": 28
      }
    }
  }
}

3.3.6 日期range

DELETE /product
POST /product/_bulk
{"index":{"_id":1}}
{"price":100,"date":"2021-01-01","productId":"BJ-1293"}
{"index":{"_id":2}}
{"price":200,"date":"2022-01-01","productId":"HRB-5421"}

GET /product/_mapping

GET /product/_search
{
  "query": {
    "range": {
      "date": {
        "gte": "now-2y"
      }
    }
  }
}

3.3.7 前綴查詢prefix

????????它會對分詞后的term進(jìn)行前綴搜索。

  • 它不會分析要搜索字符串,傳入的前綴就是想要查找的前綴;
  • 默認(rèn)狀態(tài)下,前綴查詢不做相關(guān)度分?jǐn)?shù)計算,它只是將所有匹配的文檔返回,然后賦予所有相關(guān)分?jǐn)?shù)值為1。它的行為更像是一個過濾器而不是查詢。兩者實(shí)際的區(qū)別就是過濾器是可以被緩存的,而前綴查詢不行。

prefix的原理:需要遍歷所有倒排索引,并比較每個term是否已所指定的前綴開頭。

GET /es_db/_search
{
  "query": {
    "prefix": {
      "address": {
        "value": "廣州"
      }
    }
  }
}

3.3.8 通配符查詢wildcard

????????通配符查詢:工作原理和prefix相同,只不過它不是只比較開頭,它能支持更為復(fù)雜的匹配模式。

GET /es_db/_search
{
  "query": {
    "wildcard": {
      "address": {
        "value": "*白*"
      }
    }
  }
}

3.3.9 模糊查詢fuzzy

????????在實(shí)際的搜索中,我們有時候會打錯字,從而導(dǎo)致搜索不到。在Elasticsearch中,我們可以使用fuzziness屬性來進(jìn)行模糊查詢,從而達(dá)到搜索有錯別字的情形。fuzzy查詢會用到兩個很重要的參數(shù):fuzziness、prefix_length

  • fuzziness:表示輸入的關(guān)鍵字通過幾次操作可以轉(zhuǎn)變成為ES庫里面的對應(yīng)field的字段
    • 操作是指:新增一個字符,刪除一個字符,修改一個字符,每次操作可以記做編輯距離為1;
    • 如中文集團(tuán)到中威集團(tuán)編輯距離就是1,只需要修改一個字符;
    • 該參數(shù)默認(rèn)值為0,即不開啟模糊查詢;
    • 如果fuzziness值在這里設(shè)置成2,會把編輯距離為2的東東集團(tuán)也查出來。
  • prefix_length:表示限制輸入關(guān)鍵字和ES對應(yīng)查詢field的內(nèi)容開頭的第n個字符必須完全匹配,不允許錯別字匹配;
    • 如這里等于1,則表示開頭的字必須匹配,不匹配則不返回
    • 默認(rèn)值也是0
    • 加大prefix_length的值可以提高效率和準(zhǔn)確率。
GET /es_db/_search
{
  "query": {
    "fuzzy": {
      "address": {
        "value": "白運(yùn)山",
        "fuzziness": 1    
      }
    }
  }
}

GET /es_db/_search
{
  "query": {
    "match": {
      "address": {
        "query": "廣洲",
        "fuzziness": 1
      }
    }
  }
}

注意:fuzzy模糊查詢最大模糊錯誤必須在0-2之間

  • 搜索關(guān)鍵詞長度為 2,不允許存在模糊;
  • 搜索關(guān)鍵詞長度為3-5,允許1次模糊;
  • 搜索關(guān)鍵詞長度大于5,允許最大2次模糊。

3.4 高亮highlight

????????highlight 關(guān)鍵字,可以讓符合條件的文檔中的關(guān)鍵詞高亮。highlight相關(guān)屬性:

  • pre_tags 前綴標(biāo)簽
  • post_tags 后綴標(biāo)簽
  • tags_schema 設(shè)置為styled可以使用內(nèi)置高亮樣式
  • require_field_match 多字段高亮需要設(shè)置為false

3.4.1 自定義高亮html標(biāo)簽

????????可以在highlight中使用pre_tags和post_tags

GET /products/_search
{
  "query": {
    "term": {
      "name": {
        "value": "牛仔"
      }
    }
  },
  "highlight": {
    "post_tags": ["</span>"], 
    "pre_tags": ["<span style='color:red'>"],
    "fields": {
      "*":{}
    }
  }
}

3.4.2 多字段高亮

GET /products/_search
{
  "query": {
    "term": {
      "name": {
        "value": "牛仔"
      }
    }
  },
  "highlight": {
    "pre_tags": ["<font color='red'>"],
    "post_tags": ["<font/>"],
    "require_field_match": "false",
    "fields": {
      "name": {},
      "desc": {}
    }
  }
}

3.5 bool query布爾查詢

????????布爾查詢可以按照布爾邏輯條件組織多條查詢語句,只有符合整個布爾條件的文檔才會被搜索出來。在布爾條件中,可以包含兩種不同的上下文。

  • 搜索上下文(query context):使用搜索上下文時,Elasticsearch需要計算每個文檔與搜索條件的相關(guān)度得分,這個得分的計算需使用一套復(fù)雜的計算公式,有一定的性能開銷,帶文本分析的全文檢索的查詢語句很適合放在搜索上下文中。
  • 過濾上下文(filter context):使用過濾上下文時,Elasticsearch只需要判斷搜索條件跟文檔數(shù)據(jù)是否匹配,例如使用Term query判斷一個值是否跟搜索內(nèi)容一致,使用Range query判斷某數(shù)據(jù)是否位于某個區(qū)間等。過濾上下文的查詢不需要進(jìn)行相關(guān)度得分計算,還可以使用緩存加快響應(yīng)速度,很多術(shù)語級查詢語句都適合放在過濾上下文中。

布爾查詢一共支持4種組合類型:

類型

說明

must

可包含多個查詢條件,每個條件均滿足的文檔才能被搜索到,每次查詢需要計算相關(guān)度得分,屬于搜索上下文。

should

可包含多個查詢條件,不存在must和fiter條件時,至少要滿足多個查詢條件中的一個,文檔才能被搜索到,否則需滿足的條件數(shù)量不受限制,匹配到的查詢越多相關(guān)度越高,也屬于搜索上下文。

filter

可包含多個過濾條件,每個條件均滿足的文檔才能被搜索到,每個過濾條件不計算相關(guān)度得分,結(jié)果在一定條件下會被緩存, 屬于過濾上下文。

must_not

可包含多個過濾條件,每個條件均不滿足的文檔才能被搜索到,每個過濾條件不計算相關(guān)度得分,結(jié)果在一定條件下會被緩存, 屬于過濾上下文。文章來源地址http://www.zghlxwxcb.cn/news/detail-808361.html

  • 示例
PUT /books
{
  "settings": {
    "number_of_replicas": 1,
    "number_of_shards": 1
  },
  "mappings": {
    "properties": {
      "id": {
        "type": "long"
      },
      "title": {
        "type": "text",
        "analyzer": "ik_max_word"
      },
      "language": {
        "type": "keyword"
      },
      "author": {
        "type": "keyword"
      },
      "price": {
        "type": "double"
      },
      "publish_time": {
        "type": "date",
        "format": "yyy-MM-dd"
      },
      "description": {
        "type": "text",
        "analyzer": "ik_max_word"
      }
    }
  }
}

POST /_bulk
{"index":{"_index":"books","_id":"1"}}
{"id":"1", "title":"Java編程思想", "language":"java", "author":"Bruce Eckel", "price":70.20, "publish_time":"2007-10-01", "description":"Java學(xué)習(xí)必讀經(jīng)典,殿堂級著作!贏得了全球程序員的廣泛贊譽(yù)。"}
{"index":{"_index":"books","_id":"2"}}
{"id":"2","title":"Java程序性能優(yōu)化","language":"java","author":"葛一鳴","price":46.5,"publish_time":"2012-08-01","description":"讓你的Java程序更快、更穩(wěn)定。深入剖析軟件設(shè)計層面、代碼層面、JVM虛擬機(jī)層面的優(yōu)化方法"}
{"index":{"_index":"books","_id":"3"}}
{"id":"3","title":"Python科學(xué)計算","language":"python","author":"張若愚","price":81.4,"publish_time":"2016-05-01","description":"零基礎(chǔ)學(xué)python,光盤中作者獨(dú)家整合開發(fā)winPython運(yùn)行環(huán)境,涵蓋了Python各個擴(kuò)展庫"}
{"index":{"_index":"books","_id":"4"}}
{"id":"4", "title":"Python基礎(chǔ)教程", "language":"python", "author":"Helant", "price":54.50, "publish_time":"2014-03-01", "description":"經(jīng)典的Python入門教程,層次鮮明,結(jié)構(gòu)嚴(yán)謹(jǐn),內(nèi)容翔實(shí)"}
{"index":{"_index":"books","_id":"5"}}
{"id":"5","title":"JavaScript高級程序設(shè)計","language":"javascript","author":"Nicholas C. Zakas","price":66.4,"publish_time":"2012-10-01","description":"JavaScript技術(shù)經(jīng)典名著"}


GET /books/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match": {
            "title": "java編程"
          }
        },{
          "match": {
            "description": "性能優(yōu)化"
          }
        }
      ]
    }
  }
}

GET /books/_search
{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "title": "java編程"
          }
        },{
          "match": {
            "description": "性能優(yōu)化"
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}
GET /books/_search
{
  "query": {
    "bool": {
      "filter": [
        {
          "term": {
            "language": "java"
          }
        },
        {
          "range": {
            "publish_time": {
              "gte": "2010-08-01"
            }
          }
        }
      ]
    }
  }
}

到了這里,關(guān)于ElasticSearch高級查詢語法的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • Elasticsearch數(shù)據(jù)結(jié)構(gòu)與查詢語法

    Elasticsearch是一個基于Lucene的搜索引擎,它提供了實(shí)時、可擴(kuò)展、可伸縮的搜索功能。Elasticsearch是一個分布式、實(shí)時的、多用戶的搜索和分析引擎。它是基于Lucene的搜索引擎,用于實(shí)時、可擴(kuò)展、可伸縮的搜索功能。Elasticsearch是一個分布式、實(shí)時的、多用戶的搜索和分析引擎

    2024年02月21日
    瀏覽(37)
  • 【ElasticSearch】DSL查詢語法

    【ElasticSearch】DSL查詢語法

    Elasticsearch提供了基于JSON的DSL(Domain Specific Language)來定義查詢。官方文檔: 其中,常見的查詢類型有: 查詢所有 :查詢出所有數(shù)據(jù),一般測試用。例如: 全文檢索(full text)查詢 :利用分詞器對用戶輸入內(nèi)容分詞,然后去倒排索引庫中匹配。例如: 精確查詢 :根據(jù)精確

    2024年02月16日
    瀏覽(21)
  • elasticsearch 查詢語法

    match_all 查詢所有 match 單字段匹配查詢 multi_match 多字段匹配查詢 term 精確查詢 terms 多精確查詢 fuzzy 模糊匹配選擇展示指定字段 過濾字段 includes:來指定想要顯示的字段 excludes:來指定不想要顯示的字段 exists 查詢字段age存在且id等于45的數(shù)據(jù) 組合查詢 排序+分頁

    2023年04月12日
    瀏覽(15)
  • ElasticSearch - DSL查詢語法

    ElasticSearch - DSL查詢語法

    目錄 DSL查詢分類 全文檢索查詢 精確查詢 地理查詢 復(fù)合查詢 相關(guān)性算分 算分函數(shù)查詢 BooleanQuery DSL查詢分類 Elasticsearch提供了基于JSON的DSL(Domain Specific Language)來定義查詢 常見的查詢類型包括: 查詢所有:查詢出所有的數(shù)據(jù),一般測試用;例如:match_all 全文檢索(full text)查詢

    2023年04月08日
    瀏覽(41)
  • 2、ElasticSearch高級查詢

    下面這種寫法,有沒有body體,都可以查詢所有文檔,建議寫上body體。 body體中的\\\"query\\\" 代表的是一個查詢對象,里面可以有不同的查詢屬性。 \\\"match_all\\\"表示查詢類型,match_all代表查詢所有。還有 match,term , range 等查詢類型,可以參考下面寫法。 match 匹配類型查詢,會把查詢

    2024年02月16日
    瀏覽(19)
  • Elasticsearch的高級查詢技巧

    Elasticsearch是一個基于分布式、實(shí)時、高性能、高可擴(kuò)展的搜索和分析引擎。它可以處理大量數(shù)據(jù),提供快速、準(zhǔn)確的搜索結(jié)果。Elasticsearch的查詢技巧非常重要,可以幫助我們更有效地利用Elasticsearch的功能。 在Elasticsearch中,查詢技巧主要包括以下幾個方面: 查詢語言(Query

    2024年02月21日
    瀏覽(25)
  • ElasticSearch高級查詢

    ElasticSearch高級查詢

    本內(nèi)容基本都是對請求體進(jìn)行配置,也是 ElasticSearch 的語法核心所在。 查詢都是用? GET ?請求。 分詞查詢 在 Postman 中,向 ES 服務(wù)器發(fā)? GET ?請求: http://127.0.0.1:9200/test/_search 請求體 查詢“name”包含“zhangsan2”的數(shù)據(jù) 查詢所有文檔 在 Postman 中,向 ES 服務(wù)器發(fā)? GET ?請求:

    2024年02月04日
    瀏覽(21)
  • Elasticsearch的高級查詢

    Elasticsearch的高級查詢

    目錄 一、條件查詢 1、單條件 1)路由查詢 ?2)body體查詢 2、多條件查詢 1)and---must ?2)or---should 3)范圍---filter 3、全文檢索、完全匹配、高亮顯示 ?二、聚合查詢 1、分組 2、求平均值 1)路由查詢 方法:get url :http://localhost:9200/wenzhang/_search?q=name:蠟筆 介紹:q后面跟的是字

    2024年02月13日
    瀏覽(21)
  • Elasticsearch 查詢和聚合查詢:基本語法和統(tǒng)計數(shù)量

    摘要:Elasticsearch是一個強(qiáng)大的分布式搜索和分析引擎,提供了豐富的查詢和聚合功能。本文將介紹Elasticsearch的基本查詢語法,包括預(yù)發(fā)查詢和聚合查詢,以及如何使用聚合功能統(tǒng)計數(shù)量。 Elasticsearch是一種開源的分布式搜索和分析引擎,廣泛應(yīng)用于各種場景,包括日志分析、

    2024年02月11日
    瀏覽(29)
  • elasticsearch的常用查詢語法(大全)

    參考文章網(wǎng)址:https://www.cnblogs.com/xiohao/p/12970224.html es查詢 修改時,不指定的屬性會自動覆蓋,只保留指定的屬性(不正確的修改指定文檔方式) 使用POST命令,在id后面跟_update,要修改的內(nèi)容放到doc文檔(屬性)中(正確的修改指定文檔方式) 準(zhǔn)備數(shù)據(jù) 查詢語句 輸出結(jié)果 通過觀察

    2024年02月05日
    瀏覽(20)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包