RediSearch的簡單使用與總結

Dyhuang發表於2024-05-14

前言

之前就有考慮過想要研究下RediSearch,號稱高效能全文索引的功能,這幾天閒來無事調研了一番。

RediSearch 介紹

RediSearch 是 Redis Labs 提供的一款強大且高效的搜尋和全文索引引擎。它是一個基於 Redis 的模組,允許使用者在 Redis 資料庫中進行復雜的搜尋和全文檢索操作,而無需將資料匯出到其他搜尋引擎。

推薦使用場景

RediSearch適合簡單且高效的分詞搜尋場景。
針對較為複雜的全文搜尋RediSearch肯定是不如ES這種專業的。但假設有一批地址資訊,以醫院地址舉例,省市縣地址這些基本欄位,想要快速搜尋對應地址一般如下解決方案。

  • 使用Like進行模糊匹配:太過雞肋,(比如資料是 【上海市徐彙區宜山路第六人民醫院】,搜尋關鍵詞是【上海第六】肯定是搜尋不到資料的)。
  • ES全文索引: 大材小用,殺雞焉用牛刀
  • 自實現分詞和倒排索引,最不推薦!吃力不討好,儘管市面上有很多中文分詞器和全文索引的外掛。

這時候就很適合使用RediSearch,既可以實現簡單的(倒排索引)。又不需要使用ES那麼龐大的中介軟體,整合起來也相對簡單。

RediSearch安裝

RediSearch 官方推薦的 Docker 方式來安裝並啟動。

docker run --name redisearch -p 16379:6379 -v redis-data:/data redis/redis-stack-server:latest
  • --name redisearch 對容器進行命名
  • -p 16379:6379宿主機16379對映了容器6379埠
  • -v redis-data:/data 資料卷對映
  • redis/redis-stack-server:latest 表示採用redis-stack-server的最新版本
    然後進入容器中檢視是否存在對應模組
docker exec -it redisearch redis-cli

如下圖

RediSearch 建立索引和文件

建立索引


FT.CREATE hospitalIndex ON HASH PREFIX 1 hospital: LANGUAGE  "chinese" SCHEMA id NUMERIC province TEXT SORTABLE city TEXT SORTABLE name TEXT SORTABLE
  • FT.CREATE hospitalIndex 1.0 表示建立一個名為hospitalIndex的全文索引
  • ON HASH表示資料結構為Hash
  • PREFIX 1 hospital: 表示是Key是以hospital:為字首的資料
  • LANGUAGE "chinese指定資料的語言為中文。這對文字分析和分詞很重要,因為針對不同語言有對應的分詞器。
  • SCHEMA id NUMERIC province TEXT SORTABLE city TEXT SORTABLE name TEXT SORTABLE 表示欄位結構是 id,provice city name 其中id為數字型別,其他欄位為文字參與索引

新增索引文件

ft.add hospitalIndex hospital:1 1.0 language "chinese" fields id 1 province "上海市" city "上海市" name "上海市第六人民醫院"
ft.add hospitalIndex hospital:2 1.0 language "chinese" fields id 2 province "上海市" city "上海市" name "上海交通大學醫學院附屬瑞金醫院"
ft.add hospitalIndex hospital:3 1.0 language "chinese" fields id 3 province "上海市" city "上海市" name "上海交通大學醫學院附屬新華醫院"
ft.add hospitalIndex hospital:4 1.0 language "chinese" fields id 4 province "上海市" city "上海市" name "上海交通大學醫學院附屬上海兒童醫學中心"
ft.add hospitalIndex hospital:5 1.0 language "chinese" fields id 5 province "上海市" city "上海市" name "復旦大學附屬中山醫院"
  • FT.ADD hospitalIndex hospital:1 1.0: 將一個文件 hospital:1 新增到 hospitalIndex 索引中,評分為 1.0。
  • LANGUAGE "chinese": 指定文件的語言為中文。一定要指定對應的語言,這裡會採用中文預設的分詞器
  • FIELDS: 後面跟著一系列欄位和對應的值。

查詢

ft.search [index] [keywords] language [lang]

從索引名Index中查詢對應keywords,而lang為對應語言,預設會按照語言對應的分詞器進行分詞。

示例1

ft.search hospitalIndex "上海市醫院" language "chinese" 

示例2

ft.search hospitalIndex "上海市交通大學新華醫院" language "chinese" 

示例3

ft.search hospitalIndex "附屬醫院" language "chinese" 

不足之處

示例1

儘快已經基本實現了全文索引,但由於RediSearch中的中文分詞器還是有些侷限性的。

比如下的幾個搜尋:

如上圖所示,上海市第六 是可以搜尋到資料的,但 上海第六 就無法搜尋到資料了,這是因為RediSearch中的中文分詞器對應拆分不好

示例2

如下圖

上面的幾個搜尋例子其實不夠恰當
不過我想強調的主要的目的還是 針對如果分詞中的部分詞性出現了【專業詞】(比如:阿莫西林) 或者類似【第六人】這種現象,RediSearch沒辦法正確分詞的。 是需要專業的分詞器和自定義字典的

示例3

還有個問題是RediSearch中分詞對應拆詞顆粒度過於細,針對短語的搜尋是不夠的,聚合搜尋效果很差,因為我這次的演示資料是地址資料所以不好展示處出來。
具體可以參考地址

關於RediSearch無法正常執行模糊匹配的解決方案

RediSearch 中預設的中文分詞器可能會根據版本的不一致有差異,一般都是 Friso

當然 RediSearch是支援自定義中文分詞器和自定義字典的,不過那就是另外的話題了,這裡就不提了。
具體可以參考官網:https://redis.io/docs/latest/commands/ft.dictadd/

刪除索引

ft.drop hospitalIndex

RediSearch 總結

角度 優勢 缺點
場景 適合簡單的資料型別和文字 不適合複雜的資料型別,比如富文字,長文字
整合難度 簡單指令, 方便整合 Redis知識儲備,(這個不算什麼成本吧)
執行效率 基於記憶體,搜尋速度很快 分詞效果不夠理想,資料量大會影響效能
社群生態 - 社群目前過於小眾
部署 簡單搭建,方便整合,支援叢集與橫向擴充套件 有一定的不穩定性,畢竟很少見到用於產線環境下。

參考地址

  1. RediSearch/RediSearch
  2. Redis Real-Time Search, Querying, & Indexing
  3. RediSearch 高效能的全文搜尋引擎
  4. 關於RediSearch無法正常執行模糊匹配的解決方案

相關文章