OpenSearch 2.17 三节点集群,索引里 80 万条日志向量,kNN 查询加上 tenant 过滤就报 illegal_argument_exception,原文 [knn] engine [nmslib] does not support filters,去掉 filter 能查,换 faiss 引擎才通过,测试环境是单节点所以一直没发现。
把日志和配置对完,能解释这个现象的基本就这几处。索引创建时 knn.engine 写的是 nmslib,这个引擎不支持 filter;老索引的 method 参数是 hnsw,和 faiss 的参数集不兼容;写入走的是别名,新索引被建到了旧模板上;tenant 字段是 text 类型,kNN 过滤只认 keyword 或数值。
第一件事是确认索引到底用的哪个 kNN 引擎
curl -s 'http://localhost:9200/logs-vec/_settings?pretty' | grep -i engine
再看 tenant 字段的 mapping 类型
curl -s 'http://localhost:9200/logs-vec/_mapping?pretty' | grep -A3 tenant
再往下按 faiss 新建索引并 reindex 数据
curl -X PUT 'http://localhost:9200/logs-vec-v2' -H 'Content-Type: application/json' -d '{"settings":{"index":{"knn":true}},"mappings":{"properties":{"tenant":{"type":"keyword"},"vec":{"type":"knn_vector","dimension":1024,"method":{"name":"hnsw","engine":"faiss"}}}}}'
等前面都确认过,再切别名后带 filter 复测同一查询
curl -s 'http://localhost:9200/logs-vec/_search' -H 'Content-Type: application/json' -d '{"size":5,"query":{"knn":{"vec":{"vector":[0.1,0.2],"k":5,"filter":{"term":{"tenant":"a"}}}}}}'
改之前先确认了最近有没有人动过配置,避免白查一遍。
改完先别撤,确认这几项。带 tenant 过滤的 kNN 返回 200,hits 数量与不过滤时同一租户的预期一致,日志里不再出现 nmslib does not support filters。
nmslib 在 OpenSearch 里早就停止演进,带过滤的向量检索要一开始就选 faiss;索引建好后再改引擎只能重建,模板里必须锁住 engine 字段。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。
