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,相信不会让你失望。

好了,今天的分享就到这里,如果有问题欢迎评论区交流!