Elasticsearch:是否可以通过嵌套字段对折叠结果进行排序?

时间:2019-09-05 10:40:58

标签: elasticsearch elasticsearch-aggregation

我有一个相当复杂的映射,用于存储产品,并且在每个文档中,它包含每个客户预先计算的价格的嵌套数组。

索引中每个产品可能有多个版本(具有唯一代码)。替代产品按常见的xrefs_hash分组。我正在编写的查询需要为每个客户选择最佳产品(即xrefs_hash上的汇总/崩溃),然后根据prices.weight嵌套字段的值选择最佳产品。 / p>

prices.weight字段是一个浮点数,我们已经根据商店的客户设置(他们希望如何区分自己的商品的优先级)预先计算出该浮点数。根据这些设置(存储在prices.pricing_hash中的值创建的哈希值,以便在多个客户共享相同设置的情况下,我们可以存储一组定价。

该索引包含多达300,000个产品,一旦计算并插入所有价格,最终可以生成约100,000,000个文档。

映射看起来像这样(为简便起见,简称为:)

'mappings' => [
    '_source' => [
        'enabled' => true,
    ],
    'dynamic' => false,
    'properties' => [
        'dealer_item_id' => [
            'type' => 'integer',
        ],
        'code' => [
            'type' => 'text',
            'analyzer' => 'custom_code_analyzer',
            'fields' => [
                'raw' => [
                    'type' => 'keyword',
                ],
            ],
        ],
        'xrefs' => [
            'type' => 'text',
            'analyzer' => 'custom_code_analyzer',
            'fields' => [
                'raw' => [
                    'type' => 'keyword',
                ],
            ],
        ],
        'xrefs_hash' => [
            'type' => 'keyword',
        ],
        'title' => [
            'type' => 'text',
            'analyzer' => 'custom_english_analyzer',
            'fields' => [
                'ngram_title' => [
                    'type' => 'text',
                    'analyzer' => 'custom_title_analyzer',
                ],
                'raw' => [
                    'type' => 'keyword',
                ],
            ],
        ],

        ...

        'prices' => [
            'type' => 'nested',
            'dynamic' => false,
            'properties' => [
                'pricing_hash' => [
                    'type' => 'keyword',
                    'index' => true,
                ],
                'unit_price' => [
                    'type' => 'float',
                    'index' => true,
                ],
                'pricebreaks' => [
                    'type' => 'object',
                    'dynamic' => false,
                    'properties' => [
                        'quantity' => [
                            'type' => 'integer',
                            'index' => false,
                        ],
                        'price' => [
                            'type' => 'integer',
                            'index' => false,
                        ],
                    ],
                ],
                'weight' => [
                    'type' => 'float',
                    'index' => true,
                ],
            ],
        ],
    ],
],

示例文档:

{
    "dealer_item_id": 122023,
    "code": "ABC123A",
    "xrefs": [
        "ABC123A",
        "ABC123B",
    ],
    "title": "Product A",
    "xrefs_hash": "16d5415674c8365f63329b11ffc88da109590cec",
    "prices": [
        {
            "pricebreaks": [
                {
                    "quantity": 1,
                    "price": 9.75,
                    "contract": false
                }
            ],
            "weight": 0.20512820512820512,
            "pricing_hash": "aabe06b7",
            "unit_price": 9.75,
        },
        {
            "pricebreaks": [
                {
                    "quantity": 1,
                    "price": 9.75,
                    "contract": false
                }
            ],
            "weight": 0.20512820512820512,
            "pricing_hash": "73643f3b",
            "unit_price": 9.75,
        }
    ]
},
{
    "dealer_item_id": 124293,
    "code": "ABC1234B",
    "xrefs": [
        "ABC123A",
        "ABC123B",
    ],
    "title": "Product B",
    "xrefs_hash": "16d5415674c8365f63329b11ffc88da109590cec",
    "prices": [
        {
            "contract_item": false,
            "pricebreaks": [
                {
                    "quantity": 1,
                    "price": 7.39,
                    "contract": false
                }
            ],
            "weight": 0.33829499323410017,
            "pricing_hash": "aabe06b7",
            "unit_price": 7.39,
        },
        {
            "pricebreaks": [
                {
                    "quantity": 1,
                    "price": 9.75,
                    "contract": false
                }
            ],
            "weight": 0.20512820512820512,
            "pricing_hash": "73643f3b",
            "unit_price": 9.75,
        }
    ]
},

查询示例:

{
    "track_total_hits": 100000,
    "query": {
        "bool": {
            "filter": {
                "bool": {
                    "must": [
                        {
                            "nested": {
                                "path": "prices",
                                "score_mode": "none",
                                "inner_hits": {
                                    "_source": {
                                        "include": [
                                            "prices"
                                        ]
                                    }
                                },
                                "query": {
                                    "bool": {
                                        "must": [
                                            {
                                                "term": {
                                                    "prices.pricing_hash": "aabe06b7"
                                                }
                                            }
                                        ]
                                    }
                                }
                            }
                        },
                        {
                            "term": {
                                "code.raw": "RX58022"
                            }
                        }
                    ],
                    "must_not": [
                        {
                            "term": {
                                "disabled": true
                            }
                        }
                    ]
                }
            }
        }
    },
    "_source": {
        "includes": [
            "code",
            "dealer_item_id",
            "title",
            "xrefs"
        ]
    },
    "collapse": {
        "field": "xrefs_hash",
        "inner_hits": {
            "name": "best_xrefs",
            "sort": {
                "prices.weight": "desc"
            },
            "size": 1
        }
    },
    "aggregations": {
        "xrefs_count": {
            "cardinality": {
                "field": "xrefs_hash",
                "precision_threshold": 40000
            }
        }
    }
}

我尝试使用折叠查询来选择最佳产品,但这似乎不支持按嵌套prices.weight字段进行排序。

我也尝试过基于xrefs_hash进行拼版,但这似乎无法在类别级别进行分页。

上面的示例查询几乎可以正常工作,但不会以正确的顺序返回折叠后的结果。检查查询时,似乎是用Infinity代替折叠排序,如果文档不包含排序字段,ES显然会这样做。

所以我想知道的是;是否可以:

  1. 每个唯一的xref_hash值返回1个文档
  2. 返回最高prices.weight值并与客户的pricing_hash相匹配的特定文档
  3. 也可以通过分页进行这项工作

0 个答案:

没有答案