根据过滤条件对弹性搜索结果集进行排序

时间:2013-11-28 14:49:14

标签: sorting elasticsearch

对于电子商务,我正在实施elasticsearch,以便为类别获取产品ID的排序和分页结果集。

我有一个如下所示的产品文档:

PUT /products_test/product/1
{
  "id": "1",
  "title": "foobar",
  "sort": 102,
  "categories": [
                  "28554568",
                  "28554577",
                  "28554578"
  ],
}

要获取结果集,我将按此过滤和排序:

POST /products/_search
{
    "filter": {
        "term": {
         "categories": "28554666"
        }
    },
    "sort" : [
        { "sort" : {"order" : "asc"}}
    ]
}

但是,我现在学到的要求是,产品分类取决于类别。查看上面的示例,这意味着我需要为categories数组中的每个值添加一个不同的排序值,具体取决于我想要按相应排序值排序的过滤类别。

该文件应如下所示:

PUT /products_test/product/1
{
  "id": "1",
  "title": "foobar",
  "categories": [
    { "id": "28554568", "sort": "102" },
    { "id": "28554577", "sort": "482" },
    { "id": "28554578", "sort": "2" }
  ]
}

我的查询现在应该可以这样排序:

POST /products/_search
{
    "filter": {
        "term": {
         "categories.id": "28554666"
        }
    },
    "sort" : [
        { "categories.{filtered_category_id}.sort" : {"order" : "asc"}}
    ]
}

以某种方式可以实现这个目标吗?

1 个答案:

答案 0 :(得分:1)

要实现此目的,您必须将类别存储为嵌套文档。如果没有,Elasticsearch将不知道哪种类型与哪个类别ID相关联。

然后,您必须对嵌套文档进行排序,同时过滤以选择正确的文档。

以下是您可以使用的可运行示例:https://www.found.no/play/gist/47282a07414e1432de6d

curl -XPUT "$ELASTICSEARCH_ENDPOINT/play" -d '{
    "mappings": {
        "type": {
            "properties": {
                "categories": {
                    "type": "nested"
                }
            }
        }
    }
}'


curl -XPOST "$ELASTICSEARCH_ENDPOINT/_bulk?refresh=true" -d '
{"index":{"_index":"play","_type":"type"}}
{"id":1,"title":"foobar","categories":[{"id":"28554568","sort":102},{"id":"28554577","sort":482},{"id":"28554578","sort":2}]}
{"index":{"_index":"play","_type":"type"}}
{"id":2,"title":"barbaz","categories":[{"id":"28554577","sort":0}]}
'

curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d '
{
    "query": {
        "nested": {
            "path": "categories",
            "query": {
                "term": {
                    "categories.id": {
                        "value": 28554577
                    }
                }
            }
        }
    },
    "sort": {
        "categories.sort": {
            "order": "asc",
            "nested_filter": {
                "term": {
                    "categories.id": 28554577
                }
            }
        }
    }
}
'