对象嵌套范围聚合的弹性搜索数组

时间:2021-01-07 09:12:35

标签: elasticsearch

我正在尝试对以下数据集进行范围聚合:

{
    "ProductType": 1,
                    "ProductDefinition": "fc588f8e-14f2-4871-891f-c73a4e3d17ca",
                    "ParentProduct": null,
                    "Sku": "074617",
                    "VariantSku": null,
                    "Name": "Paraboot Avoriaz/Jannu Marron Brut Marron Brown Hiking Boot Shoes",
                    "AllowOrdering": true,
                    "Rating": null,
                    "ThumbnailImageUrl": "/media/1106/074617.jpg",
                    "PrimaryImageUrl": "/media/1106/074617.jpg",
                    "Categories": [
                        "399d7b20-18cc-46c0-b63e-79eadb9390c7"
                    ],
                    "RelatedProducts": [],
                    "Variants": [
                        "84a7ff9f-edf0-4aab-87f9-ba4efd44db74",
                        "e2eb2c50-6abc-4fbe-8fc8-89e6644b23ef",
                        "a7e16ccc-c14f-42f5-afb2-9b7d9aefbc5c"
                    ],
                    "PriceGroups": [
                        "86182755-519f-4e05-96ef-5f93a59bbaec"
                    ],
                    "DisplayName": "Paraboot Avoriaz/Jannu Marron Brut Marron Brown Hiking Boot Shoes",
                    "ShortDescription": "",
                    "LongDescription": "<ul><li>Paraboot Avoriaz Mountaineering Boots</li><li>Marron Brut Marron (Brown)</li><li>Full leather inners and uppers</li><li>Norwegien Welted Commando Sole</li><li>Hand made in France</li><li>Style number : 074617</li></ul><p>As featured on <a href=\"http://www.pritchards.co.uk/shoes-trainers-11/paraboot-avoriaz-jannu-marron-brut-brown-20879.htm\">Pritchards.co.uk</a></p>",
                    "UnitPrices": {
                        "EUR 15 pct": 343.85
                    },
                    "Taxes": {
                        "EUR 15 pct": 51.5775
                    },
                    "PricesInclTax": {
                        "EUR 15 pct": 395.4275
                    },
                    "Slug": "paraboot-avoriazjannu-marron-brut-marron-brown-hiking-boot-shoes",
                    "VariantsProperties": [
                        {
                            "Key": "ShoeSize",
                            "Value": "8"
                        },
                        {
                            "Key": "ShoeSize",
                            "Value": "10"
                        },
                        {
                            "Key": "ShoeSize",
                            "Value": "6"
                        }
                    ],
                    "Guid": "0d4f6899-c66a-4416-8f5d-26822c3b57ae",
                    "Id": 178,
                    "ShowOnHomepage": true
                }

我正在聚合具有以下映射的 VariantsProperties

"VariantsProperties": {
                    "type": "nested",
                    "properties": {
                        "Key": {
                            "type": "keyword"
                        },
                        "Value": {
                            "type": "keyword"
                        }
                    }
                }

术语聚合使用以下代码可以正常工作:

{
    "aggs": {
        "Nest": {
            "nested": {
                "path": "VariantsProperties"
            },
            "aggs": {
                "fieldIds": {
                    "terms": {
                        "field": "VariantsProperties.Key"
                    },
                    "aggs": {
                        "values": {
                            "terms": {
                                "field": "VariantsProperties.Value"
                            }
                        }
                    }
                }
            }
        }
    }
}

但是,当我尝试进行范围聚合以使鞋子的尺码介于 8 到 12 之间时,例如:

{
    "aggs": {
        "Nest": {
            "nested": {
                "path": "VariantsProperties"
            },
            "aggs": {
                "fieldIds": {
                    "range": {
                        "field": "VariantsProperties.Value",
                        "ranges": [ { "from": 8, "to": 12 }]
                    }
                }
            }
        }
    }
}

我收到以下错误:

{
    "error": {
        "root_cause": [
            {
                "type": "illegal_argument_exception",
                "reason": "Field [VariantsProperties.Value] of type [keyword] is not supported for aggregation [range]"
            }
        ],
        "type": "search_phase_execution_exception",
        "reason": "all shards failed",
        "phase": "query",
        "grouped": true,
        "failed_shards": [
            {
                "shard": 0,
                "index": "product-avenueproductindexdefinition-24476f82-en-us",
                "node": "ejgN4XecT1SUfgrhzP8uZg",
                "reason": {
                    "type": "illegal_argument_exception",
                    "reason": "Field [VariantsProperties.Value] of type [keyword] is not supported for aggregation [range]"
                }
            }
        ],
        "caused_by": {
            "type": "illegal_argument_exception",
            "reason": "Field [VariantsProperties.Value] of type [keyword] is not supported for aggregation [range]",
            "caused_by": {
                "type": "illegal_argument_exception",
                "reason": "Field [VariantsProperties.Value] of type [keyword] is not supported for aggregation [range]"
            }
        }
    },
    "status": 400
}

有没有办法将术语聚合“转换”为范围聚合,而无需更改架构?我知道我可以通过从术语聚合中提取数据并从中构建范围来自己构建范围,但是,我更喜欢弹性本身的解决方案。

1 个答案:

答案 0 :(得分:1)

有两种方法可以解决这个问题:

选项 A:使用脚本而不是字段。此选项无需重新索引您的数据即可使用,但根据您的数据量,性能可能会受到影响。

POST test/_search
{
  "aggs": {
    "Nest": {
      "nested": {
        "path": "VariantsProperties"
      },
      "aggs": {
        "fieldIds": {
          "range": {
            "script": "Integer.parseInt(doc['VariantsProperties.Value'].value)",
            "ranges": [
              {
                "from": 8,
                "to": 12
              }
            ]
          }
        }
      }
    }
  }
}

选项 B:在映射中添加 integer sub-field

PUT my-index/_mapping
{
  "properties": {
    "VariantsProperties": {
      "type": "nested",
      "properties": {
        "Key": {
          "type": "keyword"
        },
        "Value": {
          "type": "keyword",
          "fields": {
            "numeric": {
              "type": "integer",
              "ignore_malformed": true
            }
          }
        }
      }
    }
  }
}

修改映射后,您可以在索引上运行 _update_by_query 以重新索引 VariantsProperties.Value 数据

PUT my-index/_update_by_query

最后,当最后一条命令完成后,您可以在 range 字段上运行 VariantsProperties.Value.numeric 聚合。

另请注意,从长远来看,这一秒会更高效。