查询以在数组中搜索嵌套的匹配项/不匹配项



如何编写DSL查询来为数组xxx中的所有对象选择具有JSON对象的文档,其中字段configs_1.a_addrconfigs_2.b_addr不匹配?

{
"name": "steve_doc_45",
"xxx": [
{
"name": "s1",
"configs_1": {
"a_addr": "10.1.2.3",
"a_mask": "255.255.224.0"
},
"configs_2": {
"b_addr": "10.1.2.3",
"b_mask": "255.255.224.0"
}
},
{
"name": "s2",
"configs_1": {
"a_addr": "10.5.5.5",
"a_mask": "255.255.224.0"
},
"configs_2": {
"b_addr": "10.6.6.6",
"b_mask": "255.255.224.0"
}
}
],
"other": "stuff"
}

在本例中,文档应该匹配,因为在名为s2的对象中,值10.5.5.510.6.6.6不匹配。

如果从数组xxx中删除了此对象,则此文档应与DSL查询匹配,因为名称为s1的对象具有匹配字段,并且它是数组xxx中唯一的对象。

您需要为此使用脚本查询。

查询

{
"query": {
"bool": {
"filter": {
"nested": {
"path": "xxx",
"query": {
"script": {
"script": """
if (doc['xxx.configs_1.a_addr.keyword'].value != doc['xxx.configs_2.b_addr.keyword'].value) 
{
return true;
}
return false;
"""
}
}
}
}
}
}
}

更新

在嵌套类型中,数组的每个对象都被视为一个单独的文档,即字段之间的关系得到维护。

在对象类型的情况下,场的多个实例被展平作为无序数组。

请仔细测试,doc[]只存储唯一值。若名称不是唯一的,那个么循环将只运行一次并跳过第二个对象。

{
"query": {
"script": {
"script": """
for(int i=0; i<doc['xxx.name.keyword'].length; i++)
{
if (doc['xxx.configs_1.a_addr.keyword'][i] != doc['xxx.configs_2.b_addr.keyword'][i]) 
{
return true;
}  
}
return false;
"""
}
}
}

我无法直接解决此问题。从中长期来看,我打算(1(将Elasticsearch升级到新版本,(2(重构索引以使用显式映射,这样我就可以利用@JaspreetChahal的好建议。

同时,在短期内,我修补了数据源上传器,以明确检查此条件,并在消息字段(字符串数组(中添加注释,然后我可以直接使用DSL查询字符串查询(也可以使用通配符(搜索该字段。这是有效的。

最新更新