日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

白话Elasticsearch01- 结构化搜索之使用term query来搜索数据

發布時間:2025/3/21 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 白话Elasticsearch01- 结构化搜索之使用term query来搜索数据 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 需求描述
  • ES版本
  • _bulk 批量寫幾條數據
  • _bulk 用法
  • 返回結果分析
  • 字段Dynamic Mapping
  • Dynamic Mapping 中 text類型的字段
  • 查看分詞
    • field
    • field.keyword
  • 幾個小例子
    • 根據用戶ID搜索帖子
    • 搜索沒有隱藏的帖子
    • 根據發帖日期搜索帖子
    • 根據帖子ID搜索帖子
    • 刪除索引,指定articleID的類型

需求描述

這個系列我們來跟著中華石杉老師來系統的學習下ES

課程地址: https://www.roncoo.com/view/55

需求背景: 一個普通的論壇,根據用戶ID、是否隱藏、帖子ID、發帖日期來搜索帖子


ES版本

我這里用的版本是ES6.4.1 , 只要是5.X以上的版本都使用。目前ES的版本已經到了7.0.

Kibana用的也是對應的kibana-6.4.1-windows-x86_64

Term Filter 不推薦使用了,推薦使用 Term Query

https://www.elastic.co/guide/en/elasticsearch/reference/6.4/query-dsl-term-filter.html#query-dsl-term-filter


6.4版本的 Term Query說明

https://www.elastic.co/guide/en/elasticsearch/reference/6.4/query-dsl-term-query.html


_bulk 批量寫幾條數據

POST /forum/article/_bulk { "index": { "_id": 1 }} { "articleID" : "XHDK-A-1293-#fJ3", "userID" : 1, "hidden": false, "postDate": "2017-01-01" } { "index": { "_id": 2 }} { "articleID" : "KDKE-B-9947-#kL5", "userID" : 1, "hidden": false, "postDate": "2017-01-02" } { "index": { "_id": 3 }} { "articleID" : "JODL-X-1937-#pV7", "userID" : 2, "hidden": false, "postDate": "2017-01-01" } { "index": { "_id": 4 }} { "articleID" : "QQPX-R-3956-#aD8", "userID" : 2, "hidden": true, "postDate": "2017-01-02" }

_bulk 用法

BULK API官網說明: https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-bulk.html

簡單說下_bulk api , 批量執行,對執行的json串有嚴格的格式要求,不要格式化JSON串


返回結果分析

直接在kibana的DevTool中執行上述JSON即可

返回結果

#! Deprecation: the default number of shards will change from [5] to [1] in 7.0.0; if you wish to continue using the default of [5] shards, you must manage this on the create index request or with an index template {"took": 1581,"errors": false,"items": [{"index": {"_index": "forum","_type": "article","_id": "1","_version": 1,"result": "created","_shards": {"total": 2,"successful": 1,"failed": 0},"_seq_no": 0,"_primary_term": 1,"status": 201}}......篇幅原因,省略其他三個的顯示}] }

結果說明:

  • took: query的時間,不包括fetch

再看下_shard節點下的total和successful信息

  • total: 2 一共兩個shard需要執行 ,一個primary shard ,一個
    replicas shard . 因為我們在同一個機器上起的(默認使用的 主shard 5 副本shard 1的配置)。 主shard 和 副本shard不能在同一個node上,所以該副本shard并未分配,所以這里successful 為1 。

通過head插件我們也可以窺之一二


字段Dynamic Mapping

  • POST /forum/article/_bulk es會自動創建名為forum的index和名為article的 type
  • 未提前設置field類型的話,es會通過Dynamic Mapping的方式來自動映射字段類型 ,我們來看下 GET /forum/_mapping/article
執行: GET /forum/_mapping/article返回: {"forum": {"mappings": {"article": {"properties": {"articleID": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},"hidden": {"type": "boolean"},"postDate": {"type": "date"},"userID": {"type": "long"}}}}} }

Dynamic Mapping 中 text類型的字段

我們重點來看下 articleID

  • es 5.x版本中對于type=text,默認會設置兩個field, 一個是field本身,比如articleID,就是分詞的, 另外一個,就是field.keyword,在這里就是用的話articleID.keyword,默認不分詞,最多保留256個字符("ignore_above": 256)

articleID.keyword,是es新版本內置建立的field,就是不分詞的。所以一個articleID過來的時候,會建立兩次索引,一次是自己本身,是要分詞的,分詞后放入倒排索引;
另外一次是基于articleID.keyword,不分詞,保留256個字符最多,直接一個字符串放入倒排索引中。

所以term filter,對text過濾,可以考慮使用內置的field.keyword來進行匹配。但是有個問題,默認就保留256個字符。所以盡可能還是自己去手動建立索引,指定not_analyzed吧。在新版本的es中,不需要指定not_analyzed也可以,將type=keyword即可。

"articleID": {"type": "text","fields": {"keyword": {"type": "keyword","ignore_above": 256}}},

查看分詞

查看下Dynamic mapping下,text類型的分詞

field

GET /forum/_analyze {"field": "articleID","text": "XHDK-A-1293-#fJ3" }

可以看到 articleID建立索引的時候,XHDK-A-1293-#fJ3被分詞成了 xhdk,a,1293,fj3

默認是analyzed的text類型的field,建立倒排索引的時候,就會對所有的articleID分詞,分詞以后,原本的articleID就沒有了,只有分詞后的各個word存在于倒排索引中。所以根據XHDK-A-1293-#fJ3 去查詢,肯定是在 xhdk,a,1293,fj3 中查找不到數據的。


field.keyword

GET /forum/_analyze {"field": "articleID.keyword","text": "XHDK-A-1293-#fJ3" }

term,是不對搜索文本分詞的,直接將輸入的內容去倒排索引中匹配,XHDK-A-1293-#fJ3 --> XHDK-A-1293-#fJ3;但是articleID建立索引的時候,XHDK-A-1293-#fJ3 --> xhdk,a,1293,fj3 ,所以使用 articleID是查不到的, articleID.keyword 是可以查到的。 如下所示


幾個小例子

term filter/query:對搜索文本不分詞,直接拿去倒排索引中匹配,你輸入的是什么,就去匹配什么。 比如說,如果對搜索文本進行分詞的話,“helle world” --> “hello”和“world”,兩個詞分別去倒排索引中匹配 。 term,“hello world” --> “hello world”,直接去倒排索引中匹配“hello world”

這里我們不關心相關度即_score,僅僅是希望通過filter過濾出來數據,所以 使用了 constant_score , 設置相關度都是1.

先通過head插件看下數據


根據用戶ID搜索帖子

GET /forum/article/_search {"query": {"constant_score": {"filter": {"term": {"userID": 1}}}} }

Term Query的寫法(推薦)

GET /forum/article/_search {"query": {"term": {"userID": "1"}} }

搜索沒有隱藏的帖子

GET /forum/article/_search {"query": {"constant_score": {"filter": {"term": {"hidden": false}}}} }

Term Query的寫法(推薦)

{"query": {"term": {"hidden": false}} }

根據發帖日期搜索帖子

GET /forum/article/_search {"query": {"constant_score": {"filter": {"term": {"postDate": "2017-01-02"}}}} }

Term Query的寫法(推薦)

GET /forum/article/_search {"query": {"term": {"postDate": "2017-01-02"}} }

根據帖子ID搜索帖子

GET /forum/article/_search {"query": {"constant_score": {"filter": {"term": {"articleID": "QQPX-R-3956-#aD8"}}}} }

Term Query的寫法(推薦)

GET /forum/article/_search {"query": {"term": {"articleID": "QQPX-R-3956-#aD8"}} }

刪除索引,指定articleID的類型

這種Dynamic mapping的情況,肯定是查找不到數據了,要么指定 articleID.keyword。 更推薦自己設置類型,設置成 not_analyzed,或者直接將articleID設置為keyword更加方便。

那我們按照自己設置字段類型keyword的方式來演示下吧

先刪掉原來的forum索引

DELETE /forum

手動設置 articleID的類型為 keyword

PUT /forum {"mappings":{"article":{"properties":{"articleID":{"type":"keyword"}}}} }

這樣的話,就建好了一個 只有一個字段的type. 字段類型確定后無法修改,因為涉及到底層lucene的全文檢索。 但是可以增加字段,通過如下的方式,_bulk寫入數據的時候,新增幾個字段,因為沒有指定字段類型,所以是Dynamic Mapping的方式創建的

POST /forum/article/_bulk { "index": { "_id": 1 }} { "articleID" : "XHDK-A-1293-#fJ3", "userID" : 1, "hidden": false, "postDate": "2017-01-01" } { "index": { "_id": 2 }} { "articleID" : "KDKE-B-9947-#kL5", "userID" : 1, "hidden": false, "postDate": "2017-01-02" } { "index": { "_id": 3 }} { "articleID" : "JODL-X-1937-#pV7", "userID" : 2, "hidden": false, "postDate": "2017-01-01" } { "index": { "_id": 4 }} { "articleID" : "QQPX-R-3956-#aD8", "userID" : 2, "hidden": true, "postDate": "2017-01-02" }

看下 field的類型

GET /forum/_mapping/article


再次查詢下 ,指定articleID的類型為keyword,查詢到了數據。

總結一下 term

(1)term filter:根據exact value進行搜索,數字、boolean、date天然支持
(2)text類型的字段需要建索引時指定為not_analyzed或者設置為keyword,才能用term query
(3)term 相當于SQL中的單個where條件


總結

以上是生活随笔為你收集整理的白话Elasticsearch01- 结构化搜索之使用term query来搜索数据的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。