Elasticsearch - 按优先级例外过滤和按名称排序

时间:2017-03-07 15:07:16

标签: javascript node.js sorting elasticsearch indexing

我尝试使用优先级例外按名称进行过滤和排序,这意味着即使结果按字母顺序排序,我也希望首先显示特定名称。

例如 - 这是我的基本查询

{
  "from": 0,
  "size": 500,
  "min_score": 0.15,
  "query": {
    "filtered": {
      "filter": {
        "bool": {
          "must": [
            {
              "exists": {
                "field": "brand.id"
              }
            }
          ]
        }
      }
    }
  },
  "sort": [
    {
      "brand.names.1.raw": "asc"
    }
  ]
}

简而言之,我想要这个阵列[" pepsi" ," rc-cola"," coca-cola"]通过将最高优先级分配给" rc-cola"所以它将被分类为[" rc-cola"," coca-cola"," pepsi"]

现在它按字母顺序排序。 我想到了一些可行的想法:

  1. 添加"应该"通过"匹配"提升。但后来我遇到了问题 按" _score"排序,它打破了我的字母排序,虽然我首先排序" _score"并通过品牌名称。例如,将此添加到" bool":"应该":[{"匹配":{" brand.id":{&# 34;查询":34709"升压" 20}}}

  2. 我试过"聚合"这样第一个查询(桶)就可以了 "匹配"具体的品牌名称和字母内部排序, 第二个查询只会按字母顺序排序。但我完全搞砸了。

  3. 我必须使用过滤 - >过滤器,我不能使用脚本查询。 感谢。

    更新 以下是文档的示例以及如何对其进行排序。 我想要" ccc"品牌首先要优先考虑,请帮我更新我的询问。

    {
      "_index": "retailer1",
      "_type": "product",
      "_id": "1",
      "_score": null,
      "_source": {
        "id": 1,
        "brand": {
          "names": {
            "1": "aaa"
          },
          "id": 405
        }
      },
      "sort": [
        "aaa"
      ]
    },
    {
      "_index": "retailer1",
      "_type": "product",
      "_id": "2",
      "_score": null,
      "_source": {
        "id": 2,
        "brand": {
          "names": {
            "1": "bbb"
          },
          "id": 406
        }
      },
      "sort": [
        "bbb"
      ]
    },
    {
      "_index": "retailer1",
      "_type": "product",
      "_id": "3",
      "_score": null,
      "_source": {
        "id": 3,
        "brand": {
          "names": {
            "1": "ccc"
          },
          "id": 407
        }
      },
      "sort": [
        "ccc"
      ]
    },
    

3 个答案:

答案 0 :(得分:4)

如果使用Elasticsearch版本1.x,以下查询应该为您提供预期结果: (如果需要,可能需要适应一些原始字段)

{
  "from": 0,
  "size": 500,
  "query": {
    "filtered": {
      "query": {
        "bool": {
          "should": [
            {
              "term": {
                "brand.names.1": "ccc",
                "boost": 10
              }
            },
            {
              "exists": {
                "field": "brand.id"
              }
            }
          ]
        }
      },
      "filter": {
        "exists": {
          "field": "brand.id"
        }
      }
    }
  },
  "sort": [
    "_score",
    {
      "brand.names.1": {
        "order": "asc"
      }
    }
  ]
}

在Elasticsearch The filtered query is replaced by the bool query的更高版本上, 这个查询应该完成这项工作(如果需要,可以使用与之前的相同的改编,以便使用原始字段)

{
  "from": 0,
  "size": 500,
  "query": {
    "bool": {
      "filter": {
        "exists": {
          "field": "brand.id"
        }
      },
      "should": [
        {
          "term": {
            "brand.names.1": "ccc"
          }
        }
      ]
    }
  },
  "sort": [
    "_score",
    {
      "brand.names.1": {
        "order": "asc"
      }
    }
  ]
}

在这两种情况下,如果你想让顶部按照给定的顺序填充多个首选匹配,你可以使用boost功能

答案 1 :(得分:3)

我在这里测试过localy。此外,为了简化查询,请询问名称,但不要使用品牌IDS,因为您的品牌可能有很多名称。如果您仍希望对名称进行排序,则可以根据需要修改脚本

POST stack/_search
{
  "query": {
    "function_score": {
      "boost_mode": "replace",
      "query": {
        "bool": {
          "must": [
            {
              "exists": {
                "field": "brand.id"
              }
            }
          ]
        }
      },
      "script_score": {
        "script": {
          "params": {
            "ids": [
              406,
              405
            ]
          },
          "inline": "return params.ids.indexOf(doc['brand.id'].value) > -1 ? 1000 - params.ids.indexOf(doc['brand.id'].value) : _score;"
        }
      }
    }
  }
}

答案 2 :(得分:3)

如果在索引时知道品牌的优先级,那么您可以直接在您的文档中将其编入索引,如:

"brand": {
      "name": "ccc",
      "priority":1000,
      "id": 407
    }

要显示在顶部的品牌可以具有较高的受欢迎度值,而其余品牌可以具有分配给较低值的受欢迎度值。

通过这种方式对其进行索引,您可以使用brand.popularity作为主要排序并将brand.names作为辅助排序直接对其进行排序

"sort" : [
        { "brand.priority" : {"order" : "desc"}},
        { "brand.name" : {"order" : "asc" }}
    ]