全文检索
什么是全文检索
向量检索能够捕捉文本间的语义关系,即使检索关键词不完全匹配,也能返回相关结果,对模糊表达或描述性问题具有较强的容错能力。同时向量检索可以在多模态数据(如文本、图像、音频)中使用,适配更复杂的检索需求,这些特性使向量检索在RAG、推荐系统和智能搜索中表现优异。
然而向量检索依赖于模型的语义理解能力,但在某些情况下,模型可能无法正确捕捉到某些特定领域的细微差别,也无法实现精确匹配,比如检索一个特定ID、一个人名字等场景,向量检索表现往往不佳。同时向量都是浮点数字,其透明性及可解释性对人类有天然的障碍,检索效果不佳时,开发人员往往难以调优。而这洽洽是传统全文检索技术的优势。
全文检索通常基于倒排索引(Inverted Index),能够实现对关键词的精确匹配。当用户查询包含特定的词或短语时,全文检索可以迅速定位并返回包含这些词的文档,确保结果的准确性和相关性,这在法律文件、医学文献等需要精确匹配的场景中尤为重要。
全文检索的优势
百度VectorDB从2.0内核版本开始,也引入了对全文检索的支持,其具备以下几个关键特性:
- 全新自研的倒排索引结构,基于高性能KV引擎而构建
- 业界少有的全实时方案,文档写入成功后只要符合检索条件就一定可以检索到,而ES类系统只能称为近实时检索系统
- 基于百度搜索自研分词器,分词器基于百度NLP内部自主研发的DeepCRF模型,该模型凝聚了百度在中文搜索领域十几年的技术积累,其模型性能与准确率均处于业界领先地位
全文检索使用示例
接下来,通过一个例子展示如何使用百度VectorDB的全文检索功能。
1、创建带倒排索引的表
1import time
2import json
3import random
4
5import pymochow
6import logging
7from pymochow.configuration import Configuration
8from pymochow.auth.bce_credentials import BceCredentials
9from pymochow.exception import ClientError, ServerError
10from pymochow.model.schema import (
11 Schema,
12 Field,
13 SecondaryIndex,
14 FilteringIndex,
15 VectorIndex,
16 InvertedIndex,
17 InvertedIndexParams
18)
19from pymochow.model.enum import (
20 FieldType, ElementType, IndexType, InvertedIndexAnalyzer, InvertedIndexParseMode, MetricType, ServerErrCode,
21 InvertedIndexFieldAttribute
22)
23from pymochow.model.enum import TableState, IndexState
24from pymochow.model.table import (
25 Partition,
26 Row,
27 FloatVector,
28 BM25SearchRequest,
29 HybridSearchRequest
30)
31
32logging.basicConfig(filename='demo.log', level=logging.DEBUG,
33 format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
34logger = logging.getLogger(__name__)
35
36if __name__ == "__main__":
37 account = 'root'
38 api_key = 'xxxxxxxx'
39 endpoint = 'http://xx.xx.xx.xx:5287' #endpoint from VectorDB console
40
41 config = Configuration(credentials=BceCredentials(account, api_key),
42 endpoint=endpoint)
43 client = pymochow.MochowClient(config)
44
45 """create database"""
46 database = 'test_db'
47 table_name = 'test_table_with_bm25_search'
48 db = client.create_database(database)
49
50 """create table"""
51 fields = []
52 fields.append(Field("docID", FieldType.STRING, primary_key=True,
53 partition_key=True, auto_increment=False, not_null=True))
54 fields.append(Field("chunkID", FieldType.STRING, primary_key=True, not_null=True))
55 fields.append(Field("title", FieldType.TEXT, not_null=True))
56 fields.append(Field("content", FieldType.TEXT, not_null=True))
57 fields.append(Field("size", FieldType.UINT64, not_null=True))
58 fields.append(Field("meta", FieldType.STRING, not_null=True))
59
60 indexes = []
61 indexes.append(InvertedIndex(index_name="title_content_inverted_index",
62 fields=["title", "content"],
63 field_attributes=[InvertedIndexFieldAttribute.NOT_ANALYZED, InvertedIndexFieldAttribute.ANALYZED],
64 params=InvertedIndexParams(analyzer=InvertedIndexAnalyzer.CHINESE_ANALYZER,
65 parse_mode=InvertedIndexParseMode.COARSE_MODE)))
66 db.create_table(
67 table_name=table_name,
68 replication=3,
69 partition=Partition(partition_num=3),
70 schema=Schema(fields=fields, indexes=indexes)
71 )
72
73 while True:
74 time.sleep(2)
75 table = db.describe_table(table_name)
76 if table.state == TableState.NORMAL:
77 break
78
79 table = db.table(table_name)
上述代码在test_db中新建了一张test_table_with_bm25_search表,并新建了名为title_content_inverted_index的倒排索引,该索引将为表每行数据的title、content列构建倒排索引结构,其中title列内容不分词(类似于ES的keyword),而content列内容需要分词。
2、灌入数据
1"""insert some rows into table"""
2rows = [
3 Row(docID='doc_589412-897452-536331',
4 chunkID='chunk_0000',
5 title='科比.布莱恩特',
6 content='科比·布莱恩特(Kobe Bryant),绰号“黑曼巴”,是NBA历史上最伟大的球员之一。他于1978年出生于美国宾夕法尼亚州,1996年直接从高中进入NBA,
7加入洛杉矶湖人队,开启了传奇的20年职业生涯',
8 size=100,
9 meta='{"createAt" : "2024-12-25"}'),
10
11 Row(docID='doc_589412-897452-536331',
12 chunkID='chunk_0001',
13 title='科比.布莱恩特',
14 content='科比以极强的得分能力和坚韧的意志著称,职业生涯五次夺得NBA总冠军,两次荣膺总决赛MVP,并18次入选全明星赛。他职业生涯总得分超过33000分>,位列历史前列',
15 size=100,
16 meta='{"createAt" : "2024-12-25"}'),
17
18 Row(docID='doc_589412-897452-536331',
19 chunkID='chunk_0002',
20 title='科比.布莱恩特',
21 content='科比的“曼巴精神”象征着永不放弃和持续精进,不仅影响着篮球界,也激励着全球无数人。2016年退役后,他在商业和文化领域继续创造价值',
22 size=80,
23 meta='{"createAt" : "2024-12-25"}'),
24
25 Row(docID='doc_589412-897452-536331',
26 chunkID='chunk_0003',
27 title='科比.布莱恩特',
28 content='2020年,科比在直升机事故中不幸去世,震惊世界。他的精神与影响力仍在延续,激励着新一代球员和球迷',
29 size=70,
30 meta='{"createAt" : "2024-12-25"}'),
31
32 Row(docID='doc_589412-897452-536332',
33 chunkID='chunk_0000',
34 title='洛杉矶.湖人队',
35 content='洛杉矶湖人队(Los Angeles Lakers)是NBA最具传奇色彩的球队之一,成立于1947年,总部位于加利福尼亚州洛杉矶。湖人队历史悠久,共赢得17次NBA总冠军,与波士顿凯尔特人并列联盟第一',
36 size=120,
37 meta='{"createAt" : "2024-12-26"}'),
38
39 Row(docID='doc_589412-897452-536332',
40 chunkID='chunk_0001',
41 title='洛杉矶.湖人队',
42 content='湖人队以明星球员云集著称,埃尔文·约翰逊(魔术师)、卡里姆·阿卜杜尔-贾巴尔、科比·布莱恩特和勒布朗·詹姆斯等都是队史代表人物。湖人队的“Showtime”时代凭借快速攻防和华丽球风席卷联盟,而科比时代的五冠成就进一步巩固了球队的地位',
43 size=200,
44 meta='{"createAt" : "2024-12-26"}'),
45
46 Row(docID='doc_589412-897452-536332',
47 chunkID='chunk_0002',
48 title='洛杉矶.湖人队',
49 content='作为NBA最受欢迎的球队之一,湖人队不仅在竞技层面表现出色,也在全球拥有庞大的粉丝群体。湖人队象征着辉煌和荣耀,持续书写着属于自己的篮>球传奇。',
50 size=160,
51 meta='{"createAt" : "2024-12-26"}')
52]
53
54table.upsert(rows=rows)
3、执行全文检索
3.1 不带Filter条件的全文检索
1request = BM25SearchRequest(index_name="title_content_inverted_index",
2 search_text="title:科比.布莱恩特",
3 limit=10)
4res = table.bm25_search(request=request)
5logger.debug("BM25 search res: {}".format(res))
这里例子在表中检索title为'科比.布莱恩特'的数据,并返回匹配Row的全部标量列,检索结果如下:
1{metadata:{content__length:u'1581',content__type:u'application/json',request_id:u'796dc5d6-e206-40b1-b53a-6aef03d07545'},
2rows:[
3 {'row': {'docID': 'doc_589412-897452-536331', 'chunkID': 'chunk_0003', 'title': '科比.布莱恩特', 'content': '2020年,科比在直升机事故中不幸去世,震惊世界。他的精神与影响力仍在延续,激励着新一代球员和球迷', 'size': 70, 'meta': '{"createAt" : "2024-12-25"}'}, 'score': 0.7985076904296875},
4 {'row': {'docID': 'doc_589412-897452-536331', 'chunkID': 'chunk_0001', 'title': '科比.布莱恩特', 'content': '科比以极强的得分能力和坚韧的意志著称,职业生涯五次夺得NBA总冠军,两次荣膺总决赛MVP,并18次入选全明星赛。他职业生涯总得分超过33000分,位列历史前列', 'size': 100, 'meta': '{"createAt" : "2024-12-25"}'}, 'score': 0.7985076904296875},
5 {'row': {'docID': 'doc_589412-897452-536331', 'chunkID': 'chunk_0002', 'title': '科比.布莱恩特', 'content': '科比的“曼巴精神”象征着永不放弃和持续精进,不仅影响着篮球界,也激励着全球无数人。2016年退役后,他在商业和文化领域继续创造价值', 'size': 80, 'meta': '{"createAt" : "2024-12-25"}'}, 'score': 0.7985076904296875},
6 {'row': {'docID': 'doc_589412-897452-536331', 'chunkID': 'chunk_0000', 'title': '科比.布莱恩特', 'content': '科比·布莱恩特(Kobe Bryant),绰号“黑曼巴”,是NBA历史上最伟大的球员之一。他于1978年出生于美国宾夕法尼亚州,1996年直接从高中进入NBA,加入洛杉矶湖人队,开启了传奇的20年职业生涯', 'size': 100, 'meta': '{"createAt" : "2024-12-25"}'}, 'score': 0.7985076904296875}
7],
8code:0, msg:u'Success'}
3.2 带Filter的全文检索
1request = BM25SearchRequest(index_name="title_content_inverted_index",
2 search_text="title:科比.布莱恩特 AND content:总冠军",
3 filter="size >= 80",
4 limit=10)
5res = table.bm25_search(request=request)
6logger.debug("BM25 search res: {}".format(res))
这个例子在表中检索title列为'科比.布莱恩特'且content列包含'总冠军'的数据,同时要求匹配Row的size列 >= 80,以下为例子检索结果输出:
1{metadata: {content__length:u'436',content__type:u'application/json',request_id:u'fc4f94e1-0471-4724-b5e0-7113fd93ee90'},
2rows:[
3 {'row': {'docID': 'doc_589412-897452-536331', 'chunkID': 'chunk_0001', 'title': '科比.布莱恩特', 'content': '科比以极强的得分能力和坚韧的意志著称,职业生涯五次夺得NBA总冠军,两次荣膺总决赛MVP,并18次入选全明星赛。他职业生涯总得分超过33000分,位列历史前列', 'size': 100, 'meta': '{"createAt" : "2024-12-25"}'}, 'score': 1.6523597240447998}
4],
5code:0,msg:u'Success'}
更多全文检索用法,请参考百度VectorDB全文检索API。