混合检索
更新时间:2025-01-07
什么是混合检索
混合检索是一种结合了全文检索、向量检索优势的技术,实现了精确匹配与语义理解的互补,旨在提升信息检索的准确性和全面性。
混合检索的基本原理
向量检索能够捕捉文本深层的语义,对模糊查询与近义表达具有很强的容错性,同时适用于多模态检索场景,如文搜图、图搜图等,向量检索技术在当今数据检索和信息处理领域占据核心地位,特别是在大规模非结构化数据和多模态数据检索中,已成为不可或缺的关键技术。而向量检索仍存在其局限性,其往往在需精确检索的场景下,表现不佳,如检索一个特定的ID、一个人的名字,同时向量往往都是高维浮点数字,其透明性及可解释性对人类有天然的障碍,检索效果不佳时,开发人员往往难以调优。
全文检索非常适合精确匹配的场景,其核心往往是倒排索引结构,能快速从海量文档中检索包含特定关键字或短语的文档,同时其检索结果具有更强的可解释性,用户可直接看到匹配的关键词和文档片段。
混合检索的优势
- 更高的检索召回精度:通过多路召回,既保证基于语义的查询结果,也能保证企业场景必备的精确检索,是支撑企业级RAG的关键技术。
- 更丰富的适用场景,处理多样化查询: 混合检索在处理多样化的查询方面表现出色,提供与用户意图一致的全面和适应性结果
- 灵活、可自定义: 用户可自定义全文检索召回结果、向量检索召回结果在最终结果的权重,为变化的检索场景选择更合适的检索手段
混合检索使用示例
下面我们通过例子展示如何使用百度VectorDB的混合检索功能。
1、创建带倒排索引与向量索引的表
Python
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 HNSWParams
19)
20from pymochow.model.enum import (
21 FieldType, ElementType, IndexType, InvertedIndexAnalyzer, InvertedIndexParseMode, MetricType, ServerErrCode,
22 InvertedIndexFieldAttribute
23)
24from pymochow.model.enum import TableState, IndexState
25from pymochow.model.table import (
26 Partition,
27 Row,
28 FloatVector,
29 BM25SearchRequest,
30 HybridSearchRequest,
31 VectorSearchConfig,
32 VectorTopkSearchRequest
33)
34
35logging.basicConfig(filename='demo.log', level=logging.DEBUG,
36 format='%(asctime)s - %(name)s - %(levelname)s - %(message)s')
37logger = logging.getLogger(__name__)
38
39if __name__ == "__main__":
40 account = 'root'
41 api_key = 'xxxxxxxx'
42 endpoint = 'http://xx.xx.xxx.xxx:5287' # endpoint from Baidu VectoDB console
43
44 config = Configuration(credentials=BceCredentials(account, api_key),
45 endpoint=endpoint)
46 client = pymochow.MochowClient(config)
47
48 """create database"""
49 database = 'test_db'
50 table_name = 'test_hybrid_search_table'
51 db = client.create_database(database)
52
53 """create table"""
54 fields = []
55 fields.append(Field("docID", FieldType.STRING, primary_key=True,
56 partition_key=True, auto_increment=False, not_null=True))
57 fields.append(Field("chunkID", FieldType.STRING, primary_key=True, not_null=True))
58 fields.append(Field("title", FieldType.TEXT, not_null=True))
59 fields.append(Field("content", FieldType.TEXT, not_null=True))
60 fields.append(Field("size", FieldType.UINT64, not_null=True))
61 fields.append(Field("meta", FieldType.STRING, not_null=True))
62 fields.append(Field("vector", FieldType.FLOAT_VECTOR, not_null=True, dimension=1024))
63
64 indexes = []
65 indexes.append(InvertedIndex(index_name="title_content_inverted_index",
66 fields=["title", "content"],
67 field_attributes=[InvertedIndexFieldAttribute.NOT_ANALYZED, InvertedIndexFieldAttribute.ANALYZED],
68 params=InvertedIndexParams(analyzer=InvertedIndexAnalyzer.CHINESE_ANALYZER,
69 parse_mode=InvertedIndexParseMode.COARSE_MODE)))
70 indexes.append(VectorIndex(index_name="vector_idx", index_type=IndexType.HNSW,
71 field="vector", metric_type=MetricType.L2,
72 params=HNSWParams(m=32, efconstruction=200)))
73 db.create_table(
74 table_name=table_name,
75 replication=3,
76 partition=Partition(partition_num=3),
77 schema=Schema(fields=fields, indexes=indexes)
78 )
79
80 while True:
81 time.sleep(2)
82 table = db.describe_table(table_name)
83 if table.state == TableState.NORMAL:
84 break
85 table = db.table(table_name)
通过上述代码,例子新建了一张test_hybrid_search_table表,同时为表新建了2个索引: 基于title、content这2列的倒排索引、基于vector列的HNSW向量索引。
2、灌入数据
Python
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 vector=[-0.0410689041018486, 0.004214739892631769, -0.024814443662762642, 0.009914507158100605, -0.01707501709461212, 0.01465007197111845,...........]),
11
12 Row(docID='doc_589412-897452-536331',
13 chunkID='chunk_0001',
14 title='科比.布莱恩特',
15 content='科比以极强的得分能力和坚韧的意志著称,职业生涯五次夺得NBA总冠军,两次荣膺总决赛MVP,并18次入选全明星赛。他职业生涯总得分超过33000分>,位列历史前列',
16 size=100,
17 meta='{"createAt" : "2024-12-25"}',
18 vector=[...........]),
19
20 Row(docID='doc_589412-897452-536331',
21 chunkID='chunk_0002',
22 title='科比.布莱恩特',
23 content='科比的“曼巴精神”象征着永不放弃和持续精进,不仅影响着篮球界,也激励着全球无数人。2016年退役后,他在商业和文化领域继续创造价值',
24 size=80,
25 meta='{"createAt" : "2024-12-25"}',
26 vector=[...........]),
27
28 Row(docID='doc_589412-897452-536331',
29 chunkID='chunk_0003',
30 title='科比.布莱恩特',
31 content='2020年,科比在直升机事故中不幸去世,震惊世界。他的精神与影响力仍在延续,激励着新一代球员和球迷',
32 size=70,
33 meta='{"createAt" : "2024-12-25"}',
34 vector=[...........]),
35
36 Row(docID='doc_589412-897452-536332',
37 chunkID='chunk_0000',
38 title='洛杉矶.湖人队',
39 content='洛杉矶湖人队(Los Angeles Lakers)是NBA最具传奇色彩的球队之一,成立于1947年,总部位于加利福尼亚州洛杉矶。湖人队历史悠久,共赢得17次NBA总冠军,与波士顿凯尔特人并列联盟第一',
40 size=120,
41 meta='{"createAt" : "2024-12-26"}',
42 vector=[.......]),
43
44 Row(docID='doc_589412-897452-536332',
45 chunkID='chunk_0001',
46 title='洛杉矶.湖人队',
47 content='湖人队以明星球员云集著称,埃尔文·约翰逊(魔术师)、卡里姆·阿卜杜尔-贾巴尔、科比·布莱恩特和勒布朗·詹姆斯等都是队史代表人物。湖人队的“Showtime”时代凭借快速攻防和华丽球风席卷联盟,而科比时代的五冠成就进一步巩固了球队的地位',
48 size=200,
49 meta='{"createAt" : "2024-12-26"}',
50 vector=[.......]),
51
52 Row(docID='doc_589412-897452-536332',
53 chunkID='chunk_0002',
54 title='洛杉矶.湖人队',
55 content='作为NBA最受欢迎的球队之一,湖人队不仅在竞技层面表现出色,也在全球拥有庞大的粉丝群体。湖人队象征着辉煌和荣耀,持续书写着属于自己的篮>球传奇。',
56 size=160,
57 meta='{"createAt" : "2024-12-26"}',
58 vector=[........])
59 ]
60
61 table.upsert(rows=rows)
3、重建向量索引
Python
1"""rebuild vector index"""
2table.rebuild_index("vector_idx")
3while True:
4 time.sleep(2)
5 index = table.describe_index("vector_idx")
6 if index.state == IndexState.NORMAL:
7 break
4、执行混合检索
4.1 不带过滤条件的混合检索
Python
1config = VectorSearchConfig(ef=200)
2vector_request = VectorTopkSearchRequest(vector_field="vector",
3 vector=FloatVector([0.011137483641505241, -0.02655072696506977, -0.015822893008589745, -0.00819395761936903, -0.024098902940750122, -0.021009085699915886, .........]),
4 limit=None,
5 config=config)
6bm25_request = BM25SearchRequest(index_name="title_content_inverted_index",
7 search_text="title:科比.布莱恩特")
8hybrid_request = HybridSearchRequest(vector_request=vector_request,
9 vector_weight=0.2,
10 bm25_request=bm25_request,
11 bm25_weight=0.8,
12 limit=5)
13
14res = table.hybrid_search(request=hybrid_request)
15logger.debug("hybrid search res: {}".format(res))
这个例子中,我们在Table中检索与"科比.布莱恩特"相关的数据,因检索的是特定关键字,因此分别设置全文检索、向量检索的权重为0.8和0.2,检索输出如下:
Python
1{metadata:{content__length:u'2141',content__type:u'application/json',request_id:u'5b4db957-0f3f-4783-aa99-ecfc082375bf'},
2rows:[
3 {'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.8500000238418579, 'distance': 0.00540169607847929},
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.6000000238418579, 'distance': 0.0036995408590883017},
5 {'row': {'docID': 'doc_589412-897452-536331', 'chunkID': 'chunk_0002', 'title': '科比.布莱恩特', 'content': '科比的“曼巴精神”象征着永不放弃和持续精进,不仅影响着篮球界,也激励着全球无数人。2016年退役后,他在商业和文化领域继续创造价值', 'size': 80, 'meta': '{"createAt" : "2024-12-25"}'}, 'score': 0.36666667461395264, 'distance': 0.004318084102123976},
6 {'row': {'docID': 'doc_589412-897452-536331', 'chunkID': 'chunk_0003', 'title': '科比.布莱恩特', 'content': '2020年,科比在直升机事故中不幸去世,震惊世界。他的精神与影响力仍在延续,激励着新一代球员和球迷', 'size': 70, 'meta': '{"createAt" : "2024-12-25"}'}, 'score': 0.2666666805744171, 'distance': 0.005043650511652231},
7 {'row': {'docID': 'doc_589412-897452-536332', 'chunkID': 'chunk_0002', 'title': '洛杉矶.湖人队', 'content': '作为NBA最受欢迎的球队之一,湖人队不仅在竞技层面表现出色,也在全球拥有庞大的粉丝群体。湖人队象征着辉煌和荣耀,持续书写着属于自己的篮球传奇。', 'size': 160, 'meta': '{"createAt" : "2024-12-26"}'}, 'score': 0.20000000298023224, 'distance': 0.0020693386904895306}],
8code:0,msg:u'Success'}
4.2 带过滤条件的混合检索
Python
1config = VectorSearchConfig(ef=200)
2vector_request = VectorTopkSearchRequest(vector_field="vector",
3 vector=FloatVector([0.010952972806990147, -0.01763264834880829, -0.007045084144920111, -0.017448166385293007, -0.0012776943622156978, -0.002704191952943802, ........]),
4 limit=None,
5 config=config)
6bm25_request = BM25SearchRequest(index_name="title_content_inverted_index",
7 search_text="content:科比.布莱恩特和他所效忠的洛杉矶湖人队")
8hybrid_request = HybridSearchRequest(vector_request=vector_request,
9 vector_weight=0.6,
10 bm25_request=bm25_request,
11 bm25_weight=0.4,
12 filter="size <= 160",
13 limit=5)
14
15res = table.hybrid_search(request=hybrid_request)
16logger.debug("hybrid search res: {}".format(res))
在这个例子里,适当提高了向量检索结果在最终结果的权重,同时兼顾关键词的精确匹配,最终检索结果输出如下:
Python
1{metadata:{content__length:u'2242',content__type:u'application/json',request_id:u'dc541bc9-ce41-46ac-9c8a-1b0c74d6ad8a'},
2rows:[
3 {'row': {'docID': 'doc_589412-897452-536332', 'chunkID': 'chunk_0002', 'title': '洛杉矶.湖人队', 'content': '作为NBA最受欢迎的球队之一,湖人队不仅在竞技层面表现出色,也在全球拥有庞大的粉丝群体。湖人队象征着辉煌和荣耀,持续书写着属于自己的篮球传奇。', 'size': 160, 'meta': '{"createAt" : "2024-12-26"}'}, 'score': 0.800000011920929, 'distance': 0.0007152445032261312},
4 {'row': {'docID': 'doc_589412-897452-536332', 'chunkID': 'chunk_0000', 'title': '洛杉矶.湖人队', 'content': '洛杉矶湖人队(Los Angeles Lakers)是NBA最具传奇色彩的球队之一,成立于1947年,总部位于加利福尼亚州洛杉矶。湖人队历史悠久,共赢得17次NBA总冠军,与波士顿凯尔特人并列联盟第一', 'size': 120, 'meta': '{"createAt" : "2024-12-26"}'}, 'score': 0.7000000476837158, 'distance': 0.0008071861229836941},
5 {'row': {'docID': 'doc_589412-897452-536331', 'chunkID': 'chunk_0001', 'title': '科比.布莱恩特', 'content': '科比以极强的得分能力和坚韧的意志著称,职业生涯五次夺得NBA总冠军,两次荣膺总决赛MVP,并18次入选全明星赛。他职业生涯总得分超过33000分,位列历史前列', 'size': 100, 'meta': '{"createAt" : "2024-12-25"}'}, 'score': 0.7000000476837158, 'distance': 0.0011578099802136421},
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.550000011920929, 'distance': 0.004798776004463434},
7 {'row': {'docID': 'doc_589412-897452-536331', 'chunkID': 'chunk_0002', 'title': '科比.布莱恩特', 'content': '科比的“曼巴精神”象征着永不放弃和持续精进,不仅影响着篮球界,也激励着全球无数人。2016年退役后,他在商业和文化领域继续创造价值', 'size': 80, 'meta': '{"createAt" : "2024-12-25"}'}, 'score': 0.4333333373069763, 'distance': 0.0018439505947753787}],
8code:0,msg:u'Success'}