Typesense 搜索引擎实战
引言
最近在项目中需要给产品添加搜索功能,之前一直用的是 Elasticsearch,不得不说它确实强大,但那个内存占用和部署复杂度真的让人头疼。同事推荐我试试 Typesense,说它更轻量、更简单,而且性能也不错。折腾了一段时间后,发现确实挺香的,今天来跟大家分享一下我的使用体验。
什么是 Typesense
Typesense 是一个开源的分布式搜索引擎,专门为即时搜索场景设计的。它的特点是安装简单、响应速度快、支持中文分词(通过集成 zhlucene 或其他插件)。官方说它能达到毫秒级的搜索响应,这个我实际用下来确实不夸张。
跟 Elasticsearch 相比,Typesense 的学习曲线平缓很多,很多功能开箱即用,不需要写复杂的配置文件。如果你之前被 ES 的复杂配置折磨过,Typesense 绝对值得一试。
安装与启动
Typesense 支持多种安装方式,我主要说两种最常用的:
Docker 方式
docker run -d -p 8108:8108 \
-v /data/typesense-data:/data \
typesense/typesense:0.24.1 \
--data-dir /data \
--api-key=your-secret-key \
--enable-cors
启动成功后,访问 http://localhost:8108 就能看到管理界面。
二进制直接运行
下载对应平台的二进制文件,解压后直接运行:
./typesense-server --data-dir=/tmp/typesense-data --api-key=secret123
简单吧?就这么几行命令,一个搜索服务就起来了。
实战:建立索引与搜索
创建集合
首先我们创建一个集合,相当于数据库的表:
curl -X POST 'http://localhost:8108/collections' \
-H 'Content-Type: application/json' \
-H 'X-TYPESENSE-API-KEY: your-secret-key' \
-d '{
"name": "products",
"fields": [
{"name": "id", "type": "string"},
{"name": "name", "type": "string", "facet": true},
{"name": "category", "type": "string", "facet": true},
{"name": "price", "type": "float", "facet": true},
{"name": "description", "type": "string"}
],
"default_sorting_field": "price"
}'
这里我设置了几个字段,facet 表示这个字段可以用于过滤和聚合搜索,非常实用。
添加文档
往集合里添加产品数据:
curl -X POST 'http://localhost:8108/collections/products/documents' \
-H 'Content-Type: application/json' \
-H 'X-TYPESENSE-API-KEY: your-secret-key' \
-d '{
"id": "1",
"name": "iPhone 15 Pro",
"category": "手机",
"price": 7999.0,
"description": "苹果最新款智能手机,A17 Pro芯片"
}'
批量导入也很简单,准备好 JSON 文件,然后用 documents/import 接口即可。
基础搜索
现在来试试搜索功能:
curl -X GET 'http://localhost:8108/collections/products/documents/search' \
-H 'X-TYPESENSE-API-KEY: your-secret-key' \
-d 'q=iphone&query_by=name,description'
返回结果会按相关性排序,默认返回 10 条结果。可以通过 per_page 参数调整每页数量。
过滤与分面
Typesense 的过滤功能很强大,支持多条件组合:
curl -X GET 'http://localhost:8108/collections/products/documents/search' \
-H 'X-TYPESENSE-API-KEY: your-secret-key' \
-d 'q=手机&query_by=name&filter_by=category:=手机&facet_by=category,price&sort_by=price:asc'
这里我们搜索"手机",限定分类为"手机",同时按价格排序,并返回分类和价格的 facets(分面信息)。这个功能在做电商搜索时特别有用,用户可以快速看到各价格区间的商品数量。
中文分词问题
Typesense 默认对英文支持很好,但中文需要额外处理。官方推荐使用 Jieba 或者自己集成中文分词库。我的做法是在数据写入前先用 Python 的 jieba 库进行分词,然后把分词结果作为独立的字段存入 Typesense:
import jieba
text = "苹果最新款智能手机"
words = " ".join(jieba.cut(text))
结果: "苹果 最新款 智能 手机"
这样搜索时就能匹配到分词后的结果了。当然,如果你有更高级的中文搜索需求,可以考虑集成 zhlucene 或者其他中文分词插件。
与业务系统集成
在实际项目中,我用的是 Python 的 typesense-client 库来集成:
import typesense
client = typesense.Client({
'api_key': 'your-secret-key',
'nodes': [{
'host': 'localhost',
'port': '8108',
'protocol': 'http'
}]
})
搜索
results = client.collections['products'].documents.search({
'q': 'iphone',
'query_by': 'name,description',
'filter_by': 'price:<=5000'
})
for hit in results['hits']:
print(hit['document']['name'], hit['document']['price'])
其他语言也有对应的 SDK,官方文档里有详细的例子。
总结
用了一段时间 Typesense,我的感受是:它真的很适合中小型项目的搜索需求。部署简单、性能优秀、API 设计合理,不需要投入太多精力去调优。对于那些不需要 Elasticsearch 那些复杂功能的场景,Typesense 是个很好的选择。
当然,它也有局限性,比如不支持复杂的聚合查询、不适合超大规模数据等。但如果你的场景是即时搜索、电商商品搜索、文档检索这类需求,强烈建议试试 Typesense,相信不会让你失望。
好了,今天的分享就到这里,如果有问题欢迎评论区交流!
Typesense 搜索引擎实战
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法