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/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- MongoDB 核心將支援全文搜尋功能 (2.3.2)MongoDB
- MongoDB 2.4 版釋出 支援全文搜尋MongoDB
- 內部抗議太強烈,Google中國版搜尋黃了Go
- 轉享:適合做快速全文搜尋的 RedisRedis
- Elasticsearch——全文搜尋Elasticsearch
- MongoDB 2.4版本釋出 支援全文搜尋MongoDB
- Elasticsearch 的配置與使用,為了全文搜尋Elasticsearch
- ElasticSearch全文搜尋引擎Elasticsearch
- Laravel xunsearch 全文搜尋Laravel
- oracle全文搜尋功能Oracle
- ES(Elasticsearch)支援PB級全文搜尋引擎入門教程Elasticsearch
- 沒辦法了,用 MySQL 做全文檢索也挺好的MySql
- Lucene輕量級搜尋引擎,真的太強了!!!Solr 和 ES 都是基於它Solr
- 微信全文搜尋優化之路優化
- SQLite中使用全文搜尋FTSSQLite
- 如何全文搜尋oracle官方文件Oracle
- Redis全文搜尋教程之建立索引並關聯源資料Redis索引
- windows Xp 也支援/Windows
- Nebula 基於 ElasticSearch 的全文搜尋引擎的文字搜尋Elasticsearch
- SQL Server 全文搜尋功能、全文索引方式介紹SQLServer索引
- 全文搜尋引擎 Elasticsearch 入門教程Elasticsearch
- CORS 跨域, 也許這篇就夠了CORS跨域
- 不支援原子性的 Redis 事務也叫事務嗎?Redis
- 管理軟體也太難選了,中小企業選型時應該考慮這些因素!
- 使用 Laravel Scout + ElasticSearch 實現全文搜尋LaravelElasticsearch
- Django新增全文搜尋功能入門篇Django
- go 分散式全文搜尋引擎 RiotSearchGo分散式
- Lucene : 基於Java的全文搜尋引擎Java
- 在漫改這條路上,騰訊最強IP也不行
- bang 的論壇也沒徹底解決中文搜尋問題
- PHP也20歲了PHP
- IKA全文搜尋工具-桌面版(原創)
- 產品級搜尋技術-全文字索引索引
- mysql的中文全文搜尋實踐(二)薦MySql
- 程式設計也快樂: 兩隻水壺 C程式碼 搜尋版程式設計C程式
- 讓Alfred支援拼音搜尋Alfred
- 阿里排查神器,太強了!阿里
- “黑飛”太猖狂,無人機也將實名上牌?無人機