繁体   English   中英

弹性搜索:嵌套属性中的布尔查询

[英]Elastic Search: Bool Query in nested properties

假设我的数据结构如下:

 { "id": "120400871755634330808993320",
                    "name": "Metaalschroef binnenzeskant, DIN 912 RVS A4-80",
                    "description": "m16x70 cilinderschroef bzk a4-80 din912 klasse 80",
                    "fullDescription": "Metaalschroef met een binnenzeskant cilinderkop",
                    "synonyms": [],
                    "properties": [
                        {
                            "name": "draad",
                            "value": "16",
                            "sort": 99
                        },
                        {
                            "name": "lengte",
                            "value": "70",
                            "sort": 99
                        },
                        {
                            "name": "materiaal",
                            "value": "roestvaststaal",
                            "sort": 99
                        },
                        {
                            "name": "kwaliteit (materiaal)",
                            "value": "A4",
                            "sort": 99
                        },
                        {
                            "name": "DIN",
                            "value": "912",
                            "sort": 99
                        },
                        {
                            "name": "AISI",
                            "value": "316",
                            "sort": 99
                        },
                        {
                            "name": "draadsoort",
                            "value": "metrisch",
                            "sort": 99
                        },
                        {
                            "name": "Merk",
                            "value": "Elcee Holland",
                            "sort": 1
                        }
                    ]
}

如何编写布尔查询,在其中选择所有具有名称为“ draad”,值为“ 16”的属性和名称为“ lengte”且值为“ 70”的文档。

现在我有这个,但它返回0个结果:

"query" : {
    "nested" : {
        "path" : "properties",
        "query" : {
            "bool" : {
                "must" : [{
                        "bool" : {
                            "must" : [{
                                    "term" : {
                                        "properties.name" : "Merk"
                                    }
                                }, {
                                    "term" : {
                                        "properties.value" : "Facom"
                                    }
                                }
                            ]
                        }
                    }, {
                        "bool" : {
                            "must" : [{
                                    "term" : {
                                        "properties.name" : "materiaal"
                                    }
                                }, {
                                    "term" : {
                                        "properties.value" : "kunststof"
                                    }
                                }
                            ]
                        }
                    }
                ]
            }
        }
    }
}

将最高级别的“必须”替换为“应该”会返回太多结果,这很有意义,因为它可以转换为“或”。

使用must ,引擎将尝试搜索name:Merkvalue:Facom嵌套文档。 而且还带有name:materiaal value:kunststofvalue:kunststof在同一嵌套文档中不可能一次发生。

正如您所提到的,在使用should将其转换为or -的确是可能的。

问题是,您还将获得整个父文档及其所有嵌套文档。

在我自己的答案中,我演示了使用nested文档创建索引的步骤(您应将字段properties标记为嵌套类型`)。

完成这些步骤之后,您将可以通过以下查询获取结果:

{
  "_source": [
    "id",
    "name",
    "description"
  ],
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "path": "properties",
            "query": {
              "bool": {
                "should": [
                  {
                    "bool": {
                      "must": [
                        {
                          "term": {
                            "properties.name": "Merk"
                          }
                        },
                        {
                          "term": {
                            "properties.value": "Facom"
                          }
                        }
                      ]
                    }
                  },
                  {
                    "bool": {
                      "must": [
                        {
                          "term": {
                            "properties.name": "materiaal"
                          }
                        },
                        {
                          "term": {
                            "properties.value": "kunststof"
                          }
                        }
                      ]
                    }
                  }
                ]
              }
            },
            "inner_hits":{
              "size": 10
            }
          }
        }
      ]
    }
  }
}

我找到了运行良好的解决方案!

我的属性对象现在看起来像这样:

                    {
                        "name": "breedte(mm)",
                        "value": "1000",
                        "unit": "mm",
                        "sort": 99,
                        "nameSlug": "breedte-mm",
                        "slug": "breedte-mm-1000"
                    },

我添加了一个slug(包含用于键+值的规范化字符串)和一个nameslug,它是名称的规范化字符串。

我的索引是这样映射的:

                "properties": {
                    "type": "nested",
                    "include_in_parent": true,
                    "properties": {
                        "name": {
                            "type": "keyword"
                        },
                        "nameSlug": {
                            "type": "keyword"
                        },
                        "slug": {
                            "type": "keyword"
                        },
                        "sort": {
                            "type": "long"
                        },
                        "unit": {
                            "type": "text",
                            "index": false
                        },
                        "value": {
                            "type": "keyword"
                        }
                    }
                }

“ include_in_parent”在这里很重要。 它允许我执行以下查询:

"query": {
    "bool": {
      "must": [
        {
          "terms": {
            "properties.slug": [
              "merk-orbis",
              "merk-bahco"
            ]
          }
        },
        {
          "terms": {
            "properties.slug": [
              "materiaal-staal",
              "materiaal-kunststof"
            ]
          }
        }
      ]
    }
  },

该查询搜索“ merk”为“ Orbis”或“ Bahco”且“ material”为“ staal”或“ kunststof”的所有文档。

我的汇总如下所示:

"merk_query": {
          "filter": {
            "bool": {
              "must": [
                {
                  "terms": {
                    "properties.slug": [
                      "materiaal-staal",
                      "materiaal-kunststof"
                    ]
                  }
                }
              ]
            }
          },
          "aggs": {
            "merk_facets": {
              "nested": {
                "path": "properties"
              },
              "aggs": {
                "merk_only": {
                  "filter": {
                    "term": {
                      "properties.nameSlug": {
                        "value": "merk"
                      }
                    }
                  },
                  "aggs": {
                    "facets": {
                      "terms": {
                        "field": "properties.name",
                        "size": 1
                      },
                      "aggs": {
                        "facetvalues": {
                          "terms": {
                            "field": "properties.value",
                            "size": 10
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },

我运行filteraggregate过滤所有与构面匹配的文档(但不是我正在构建的当前文档)。

这种聚合的结果是这样的:

"merk_query": {
                "doc_count": 7686,
                "merk_facets": {
                    "doc_count": 68658,
                    "merk_only": {
                        "doc_count": 7659,
                        "facets": {
                            "doc_count_error_upper_bound": 0,
                            "sum_other_doc_count": 0,
                            "buckets": [
                                {
                                    "key": "Merk",
                                    "doc_count": 7659,
                                    "facetvalues": {
                                        "doc_count_error_upper_bound": 10,
                                        "sum_other_doc_count": 438,
                                        "buckets": [
                                        {
                                            "key": "Orbis",
                                            "doc_count": 6295
                                        },
                                        {
                                            "key": "DX",
                                            "doc_count": 344
                                        },
                                        {
                                            "key": "AXA",
                                            "doc_count": 176
                                        },
                                        {
                                            "key": "Talen Tools",
                                            "doc_count": 127
                                        },
                                        {
                                            "key": "Nemef",
                                            "doc_count": 73
                                        },
                                        {
                                            "key": "bonfix",
                                            "doc_count": 67
                                        },
                                        {
                                            "key": "Bahco",
                                            "doc_count": 64
                                        },
                                        {
                                            "key": "Henderson",
                                            "doc_count": 27
                                        },
                                        {
                                            "key": "Maasland Groep",
                                            "doc_count": 25
                                        },
                                        {
                                            "key": "SYSTEC",
                                            "doc_count": 23
                                        }
                                    ]
                                    }
                                }
                            ]
                        }
                    }
                }
            }
        },

这是浏览器的最终结果:

在此处输入图片说明

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM