Redis 也支援全文搜尋?這也太強了
來源:waynblog
在 2021 年我就瞭解到 RediSearch 這個專案,並已經把它用於我的開源專案 newbee-mall-pro 中。
就我的使用體驗來說,簡單場景下,用來平替 Elasticsearch 的使用場景已經足夠。像是 Elasticsearch 中常用中文分詞外掛可以用 RediSearch 替代,但是拼音轉中文外掛在 RediSearch 中還沒有功能替代,只能透過個人手段處理。
在 newbee-mall-pro 專案中,拼音搜尋我是透過先將中文轉拼音後作為拼音欄位存入 Redis 中,再透過 RediSearch 查詢拼音欄位來實現的。
RediSearch 對於我來說相比 Elasticsearch 的最大優點就是 記憶體佔用非常低,查詢效能也足夠高😂。
在我的低配 2 核 4g 記憶體的伺服器上,透過官方提供的 Redis Stack 映象部署 Redis 以及自帶模組 RediSearch 後,記憶體佔用才不到 100m。
相比部署一個 Elasticsearch 起碼需要 1g 記憶體來說,我更願意部署 RediSearch。本文大綱如下,
RediSearch 簡介
RediSearch 是一個 Redis 模組,為 Redis 提供查詢、二級索引和全文搜尋功能。
要使用 RediSearch 的功能,我們需要要先宣告一個 index(類似於 Elasticsearch 的索引)。然後就可以使用 RediSearch 的查詢語言來查詢該索引下的資料。
RediSearch 內部使用壓縮的倒排索引,所以可以用較低的記憶體佔用來實現索引的快速構建。
目前 RediSearch 最新版支援的查詢功能也比較豐富了,除了基本的文字分詞還支援聚合統計、停用詞、同義詞、拼寫檢查、結果排序、標籤查詢、向量相似度查詢以及中文分詞等。
對比 Elasticsearch
基本硬體
資料來源
RediSearch 配置
Elasticsearch 配置
版本
索引構建測試
在官方提供的索引構建測試中,RediSearch 用 221 秒的速度超過了 Elasticsearch 的 349 秒,領先 58%,
查詢效能測試
透過資料集匯入索引資料後,官方使用執行在專用負載生成器伺服器上的 32 個客戶端啟動了兩個詞的搜尋查詢。
如下圖所示,RediSearch 的吞吐量達到了 12.5K ops/sec,而 Elasticsearch 的吞吐量只有了 3.1K ops/sec,快了 4 倍。此外 RediSearch 的延遲稍好一些,平均為 8 毫秒,而 Elasticsearch 為 10 毫秒。(ops/sec 每秒運算元)
由此可見,RediSearch 在效能上對比 RediSearch 有比較大的優勢。
目前 RediSearch 已經更新到 2.0+ 版本,根據官方對於 RediSearch 2.0 版本介紹,與 RediSearch 1.6 相比,吞吐量和延遲相關的指標都提高了 2.4 倍。
RediSearch 安裝
對於目前最新的 RediSearch 2.0 版本來說,官方推薦直接使用 redis-stack-server 映象進行進行部署,也比較簡單,
docker run -d --name redis-stack-server -p 6379:6379 redis/redis-stack-server:latest
設定登入密碼
// 設定登入密碼
docker run -e REDIS_ARGS="--requirepass redis-stack" redis/redis-stack:latest
透過 redis-cli 連線檢視 RediSearch 是否安裝了 search 模組,
redis-cli -h localhost
> MODULE list
...
3) 1) "name"
2) "search"
3) "ver"
4) "20809"
5) "path"
6) "/opt/redis-stack/lib/redisearch.so"
7) "args"
8) 1) "MAXSEARCHRESULTS"
2) "10000"
3) "MAXAGGREGATERESULTS"
4) "10000"
...
索引操作
FT.CREATE 建立索引命令
> FT.CREATE idx:goods on hash prefix 1 "goods:" language chinese schema goodsName text sortable
"OK"
FT.CREATE:建立索引命令 idx:goods:索引名稱 on hash:索引關聯的資料型別,這裡指定索引基於 hash 型別的源資料構建 prefix 1 "goods:":表示索引關聯的 hash 型別源資料字首是 goods: language chinese:表示支援中文語言分詞 schema goodsName text sortable:表示欄位定義,goodsName 表示後設資料屬性名,text 表示欄位型別 sortable 表示該欄位可以用於排序
新增索引時,直接使用 hset 命令新增一個 key 字首是 "goods:" 的源資料。如下,
hset goods:1001 goodsName 小米手機
hset goods:1002 goodsName 華為手機
FT.SEARCH 查詢索引
> FT.SEARCH idx:goods1 "手機"
1) "2"
2) "goods:1001"
3) 1) "goodsName"
2) "\xe5\xb0\x8f\xe7\xb1\xb3\xe6\x89\x8b\xe6\x9c\xba"
4) "goods:1002"
5) 1) "goodsName"
2) "\xe5\x8d\x8e\xe4\xb8\xba\xe6\x89\x8b\xe6\x9c\xba"
FT.INFO 查詢指定名稱索引資訊
> FT.INFO idx:goods
1) "index_name"
2) "idx:goods1"
3) "index_options"
4) (empty list or set)
5) "index_definition"
6) 1) "key_type"
2) "HASH"
3) "prefixes"
4) 1) "goods:"
5) "default_language"
6) "chinese"
7) "default_score"
8) "1"
7) "attributes"
8) 1) 1) "identifier"
2) "goodsName"
3) "attribute"
4) "goodsName"
5) "type"
6) "TEXT"
7) "WEIGHT"
8) "1"
9) "SORTABLE"
...
FT.INFO 查詢指定名稱的索引資訊
FT.DROPINDEX 刪除索引名稱
> FT.DROPINDEX idx:goods1
"OK"
FT.DROPINDEX 刪除指定名稱索引,不會刪除 hash 型別的源資料
如果需要刪除索引資料,直接使用 del 命令刪除索引關聯的源資料即可。
Java 使用 RediSearch
對於 Java 專案直接選用 Jedis4.0 以上版本就可以使用 RediSearch 提供的搜尋功能,Jedis 在 4.0 以上版本自動支援 RediSearch,編寫 Jedis 連線 RedisSearch 測試用例,用 RedisSearch 命令建立如下,
Jedis 建立 RediSearch 客戶端
@Bean
public UnifiedJedis unifiedJedis(GenericObjectPoolConfig jedisPoolConfig) {
UnifiedJedis client;
if (StringUtils.isNotEmpty(password)) {
client = new JedisPooled(jedisPoolConfig, host, port, timeout, password, database);
} else {
client = new JedisPooled(jedisPoolConfig, host, port, timeout, null, database);
}
return client;
}
Jedis 建立索引
Schema schema = new Schema()
.addSortableTextField("goodsName", 1.0)
.addSortableTagField("tag", "|");
IndexDefinition rule = new IndexDefinition(IndexDefinition.Type.HASH)
.setPrefixes("idx:goods")
.setLanguage("chinese"); # 設定支援中文分詞
client.ftCreate(idxName,
IndexOptions.defaultOptions().setDefinition(rule),
schema);
Jedis 新增索引源資料
public boolean addGoodsIndex(String keyPrefix, Goods goods) {
Map<String, String> hash = MyBeanUtil.toMap(goods);
hash.put("_language", "chinese");
client.hset("idx:goods" + goods.getGoodsId(), MyBeanUtil.toMap(goods));
return true;
}
Jedis 中文查詢
public SearchResult search(String goodsIdxName, SearchObjVO searchObjVO, Page<SearchPageGoodsVO> page) {
// 查詢關鍵字
String keyword = searchObjVO.getKeyword();
String queryKey = String.format("@goodsName:(%s)", keyword);
Query q = new Query(queryKey);
String sort = searchObjVO.getSidx();
String order = searchObjVO.getOrder();
// 查詢是否排序
if (StringUtils.isNotBlank(sort)) {
q.setSortBy(sort, Constants.SORT_ASC.equals(order));
}
// 設定中文分詞查詢
q.setLanguage("chinese");
// 設定分頁
q.limit((int) page.offset(), (int) page.getSize());
// 返回查詢結果
return client.ftSearch(goodsIdxName, q);
}
最後聊兩句
RediSearch 是這幾年新出的一個全文搜尋引擎,藉助於 Redis 的成功,RediSearch 一出場就獲得了較高的關注度。
目前來看,我個人使用 RediSearch 作為 newbee-mall-pro 專案的全文搜尋引擎已經夠用了,它有易於安裝、索引佔用記憶體低、查詢速度快等許多優點。不過在對 Redis 叢集的支援上,RediSearch 目前只針對 Redis 企業版有解決方案,開源版還沒有,這一點需要告訴大家。
如果想要在生產環境大規模使用,我還是不太建議的。
最後本文使用的 Jedis 操作 RediSearch 相關程式碼,都在 newbee-mall-pro 專案的 JedisSearchTest 類有體現。
newbee-mall-pro:
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70024923/viewspace-2999904/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 這個太簡單了,我也不會
- Elasticsearch——全文搜尋Elasticsearch
- Elasticsearch 的配置與使用,為了全文搜尋Elasticsearch
- Laravel xunsearch 全文搜尋Laravel
- sphinx 全文搜尋引擎
- ElasticSearch全文搜尋引擎Elasticsearch
- ES(Elasticsearch)支援PB級全文搜尋引擎入門教程Elasticsearch
- 內部抗議太強烈,Google中國版搜尋黃了Go
- 民層強置六也狀先太已jti
- 沒辦法了,用 MySQL 做全文檢索也挺好的MySql
- Redis全文搜尋教程之建立索引並關聯源資料Redis索引
- Nebula 基於 ElasticSearch 的全文搜尋引擎的文字搜尋Elasticsearch
- SQL Server 全文搜尋功能、全文索引方式介紹SQLServer索引
- Lucene輕量級搜尋引擎,真的太強了!!!Solr 和 ES 都是基於它Solr
- 沒想到!AlphaZero式樹搜尋也能用來增強大語言模型推理與訓練模型
- 18. 使用MySQL之全文字搜尋MySql
- 使用 Laravel Scout + ElasticSearch 實現全文搜尋LaravelElasticsearch
- 微信全文搜尋耗時降94%?我們用了這種方案
- 不支援原子性的 Redis 事務也叫事務嗎?Redis
- CORS 跨域, 也許這篇就夠了CORS跨域
- IKA全文搜尋工具-桌面版(原創)
- 管理軟體也太難選了,中小企業選型時應該考慮這些因素!
- Laravel5.5 使用 Elasticsearch 做引擎,scout 全文搜尋LaravelElasticsearch
- 在漫改這條路上,騰訊最強IP也不行
- 使用 Postgres 的全文搜尋構建可擴充套件的事件驅動搜尋架構套件事件架構
- Elasticsearch 為了搜尋Elasticsearch
- Laravel 下 TNTSearch+jieba-PHP 實現中文全文搜尋LaravelJiebaPHP
- Spring Boot整合Postgres實現輕量級全文搜尋Spring Boot
- 使用Elasticsearch快速實現社群/部落格文章全文搜尋Elasticsearch
- VuePress 部落格優化之開啟 Algolia 全文搜尋Vue優化Go
- 有了它,Golang 也能 Eval 了Golang
- 零預算也能用SEO技巧達到Google自然搜尋結果第1名Go
- 有了這款顯微鏡 不用出門也能看世界
- 【搜尋引擎】 PostgreSQL 10 實時全文檢索和分詞、相似搜尋、模糊匹配實現類似Google搜尋自動提示SQL分詞Go
- 正也科技-轄區與指標管理系統 強化決策支援指標
- 開放搜尋開源相容版,支援Elasticsearch做搜尋召回引擎Elasticsearch
- 如何使用ABAP Restful API進行程式碼的全文搜尋RESTAPI行程
- Tantivy與Quickwit:類似Lucene的Rust全文搜尋引擎庫UIRust