05_hybrid_search_rerank.py 4.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. import random
  2. from pymilvus import AnnSearchRequest, DataType, MilvusClient, RRFRanker, WeightedRanker
  3. client = MilvusClient(uri="http://localhost:19530")
  4. def demo_rankers():
  5. # 加权排名:为某些向量场分配更高的权重,从而更加强调这些向量场。
  6. # 输入值的范围应为 [0,1],数值越接近 1 表示重要性越高。
  7. rerank = WeightedRanker(0.8, 0.3)
  8. print(f'WeightedRanker-->{rerank}')
  9. # RRFRanker(倒数排序融合):没有特定重点时使用,k 的默认值为 60,用于控制随着排名增加分数的降低速度。
  10. ranker = RRFRanker(100)
  11. print(f'RRFRanker-->{ranker}')
  12. def complex_query():
  13. # 脚本可重复运行:先清理上一次留下的 collection
  14. if client.has_collection(collection_name='demo_v3'):
  15. client.drop_collection(collection_name='demo_v3')
  16. # # 定义schema
  17. schema = client.create_schema(enable_dynamic_field=False)
  18. schema.add_field(field_name='film_id', datatype=DataType.INT64, is_primary=True)
  19. schema.add_field(field_name='filmVector', datatype=DataType.FLOAT_VECTOR, dim=5) # 向量字段
  20. schema.add_field(field_name="posterVector", datatype=DataType.FLOAT_VECTOR, dim=5) # 向量字段
  21. # #
  22. # 定义索引
  23. index_params = client.prepare_index_params()
  24. index_params.add_index(field_name='filmVector', index_type="IVF_FLAT",
  25. metric_type="L2", params={"nlist": 128})
  26. # index_type="", # 留空以使用自动索引 —— 当前 pymilvus/Milvus Lite 版本要求显式指定 index_type,这里用 'AUTOINDEX' 代替课件里的空字符串写法
  27. index_params.add_index(field_name='posterVector', index_type="AUTOINDEX",
  28. metric_type="COSINE")
  29. # 创建集合
  30. client.create_collection(collection_name='demo_v3', schema=schema, index_params=index_params)
  31. # 向量库中插入实体
  32. entities = []
  33. for _ in range(1000):
  34. # 构造实体
  35. film_id = random.randint(1, 10000)
  36. film_vector = [random.random() for _ in range(5)]
  37. poster_vector = [random.random() for _ in range(5)]
  38. entity = {"film_id": film_id, "filmVector": film_vector, "posterVector": poster_vector}
  39. entities.append(entity)
  40. client.insert(collection_name='demo_v3', data=entities)
  41. # 多向量查询(注意和批量向量查询不同)
  42. # 多向量搜索使用 hybrid_search() API 在一次调用中执行多个 ANN 搜索请求。每个 AnnSearchRequest 代表特定矢量场上的单个搜索请求。
  43. # 示例创建两个 AnnSearchRequest 实例以对两个向量字段执行单独的相似性搜索。
  44. # 创建多搜索请求 filmVector
  45. query_filmVector = [[0.8896863042430693, 0.370613100114602, 0.23779315077113428, 0.38227915951132996, 0.5997064603128835]]
  46. dense_search_params = {"data": query_filmVector,
  47. "anns_field": "filmVector", # 该参数值必须与集合模式中使用的值相同。
  48. "param": {"metric_type": "L2", "nprobe": 10}, # nprobe代表访问簇的数量
  49. "limit": 2}
  50. request_1 = AnnSearchRequest(**dense_search_params)
  51. # 创建多搜索请求 posterVector
  52. query_posterVector = [[0.02550758562349764, 0.006085637357292062, 0.5325251250159071, 0.7676432650114147, 0.5521074424751443]]
  53. sparse_search_params = {"data": query_posterVector,
  54. "anns_field": "posterVector",
  55. # 该参数值必须与集合模式中使用的值相同。
  56. "param": {"metric_type": "COSINE"},
  57. "limit": 2
  58. }
  59. request_2 = AnnSearchRequest(**sparse_search_params)
  60. reqs = [request_1, request_2]
  61. ranker = RRFRanker(100)
  62. res = client.hybrid_search(
  63. collection_name="demo_v3",
  64. reqs=reqs,
  65. ranker=ranker,
  66. limit=2
  67. )
  68. for hits in res:
  69. print("TopK results:")
  70. for hit in hits:
  71. print(hit)
  72. if __name__ == '__main__':
  73. demo_rankers()
  74. complex_query()