Solr中如何将指定向量与所有匹配搜索的文档向量计算余弦相似度或KNN
问题原因说明
你之前的方案崩溃是因为全量加载符合条件的向量一次性构建矩阵,数据量稍大就会触发内存溢出导致Solr崩溃,下面是两种适配不同场景的可行实现方案:
方案1:Solr 7.4+ 内置KNN查询(最优方案)
Solr从7.4版本开始原生支持稠密向量KNN查询,不需要手动写流表达式构建矩阵,底层会自动遍历符合过滤条件的所有文档计算相似度,内存开销极低。
- 首先修改
managed-schema配置,将vector字段定义为DenseVectorField类型,指定向量维度和相似度计算规则:
<fieldType name="knn_vector" class="solr.DenseVectorField" vectorDimension="52" similarityFunction="cosine"/> <field name="vector" type="knn_vector" indexed="true" stored="true"/>
注:你的示例向量是52维,所以
vectorDimension参数填52,similarityFunction指定为cosine即采用余弦相似度计算。
- 配置生效后直接用查询语法即可拿到KNN结果,其他过滤条件可以直接拼接在查询参数中:
q={!knn f=vector topK=5}[469,323,324,119,74,58,68,59,49,40,32,26,21,17,14,12,10,9,7,5,-642,-184,-99,-84,-79,-63,-50,-38,-30,-21,-18,-16,-17,-16,14,25,52,21,15,93,53,52,32,15,61,29,346,20,69,72,38,165]
如果需要附加其他过滤条件,比如筛选category:music的文档的KNN结果,直接拼接即可:
q=category:music AND {!knn f=vector topK=5}[469,323,324,119,74,58,68,59,49,40,32,26,21,17,14,12,10,9,7,5,-642,-184,-99,-84,-79,-63,-50,-38,-30,-21,-18,-16,-17,-16,14,25,52,21,15,93,53,52,32,15,61,29,346,20,69,72,38,165]
返回结果的score字段就是对应文档和目标向量的余弦相似度。
方案2:低版本Solr流表达式优化方案
如果你使用的Solr版本低于7.4,没有内置KNN支持,改用流表达式的scoreNodes函数逐行计算相似度再取TopK即可,内存开销仅为K的大小,不会触发崩溃:
let( testvector=array(469,323,324,119,74,58,68,59,49,40,32,26,21,17,14,12,10,9,7,5,-642,-184,-99,-84,-79,-63,-50,-38,-30,-21,-18,-16,-17,-16,14,25,52,21,15,93,53,52,32,15,61,29,346,20,69,72,38,165), docs=search(satracks, q="vector:*", // 此处可替换为你的任意过滤条件 fl="id,vector", qt="/export" ), scored=scoreNodes(docs, testvector, cosineSimilarity, vector), top5=top(scored, 5, "cosineSimilarity desc") )
该方案不会全量加载向量到内存,而是遍历每一个符合条件的文档计算相似度后仅保留TopK结果,数据量再大也不会导致Solr崩溃。
内容的提问来源于stack exchange,提问作者blisstdev
相关产品推荐
相关产品推荐

