我正在尝试使用Java SDK使用Elasticsearch脚本查询来确定作为参数传递的ID集合是否包含索引文档中的所有值。
这是一个简单的示例,它不起作用,我希望它与文档相匹配,但事实并非如此。
文档attributes
字段是一个包含单个项目[2]
的数组
BoolQueryBuilder qb = boolQuery();
Map<String, Object> params = new HashMap<String, Object>();
params.put( "list", Arrays.asList( 1L, 2L, 3L ) );
String expr = "params.list.containsAll(doc['attributes'])";
Script script = new Script( ScriptType.INLINE, "painless", expr, Collections.emptyMap(), params );
qb.should( scriptQuery( script ) );
但是,我尝试了这些有效的各种硬编码替代方案
硬编码
.contains(2)
可以正常工作BoolQueryBuilder qb = boolQuery();
Map<String, Object> params = new HashMap<String, Object>();
params.put( "list", Arrays.asList( 2L ) );
String expr = "params.list.contains(2)";
Script script = new Script( ScriptType.INLINE, "painless", expr, Collections.emptyMap(), params );
qb.should( scriptQuery( script ) );
硬编码
.containsAll([2])
可以正常工作BoolQueryBuilder qb = boolQuery();
Map<String, Object> params = new HashMap<String, Object>();
params.put( "list", Arrays.asList( 2L ) );
String expr = "params.list.containsAll([2])";
Script script = new Script( ScriptType.INLINE, "painless", expr, Collections.emptyMap(), params );
qb.should( scriptQuery( script ) );
最佳答案
必须在调用params.list
之前强制转换containsAll
元素:
{
"query": {
"bool": {
"must": [
{
"script": {
"script": {
"inline": """
params.list.stream()
.map(num -> (long) num)
.collect(Collectors.toList())
.containsAll(
doc['attributes'].stream()
.collect(Collectors.toList()))""",
"params": {
"list": [
2
]
}
}
}
}
]
}
}
}
假设您的映射确实这样定义了
atributes
:{
"mappings": {
"properties": {
"attributes": {
"type": "long"
}
}
}
}
关于elasticsearch - Elasticsearch脚本参数containsAll与文档中的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61477151/