提升弹性聚合结果

时间:2017-04-17 13:39:01

标签: sorting elasticsearch boost elasticsearch-net elasticsearch-aggregation

我有product s的弹性索引,每个产品都有Brand个归属,我“必须”创建一个aggregation,返回Brand个产品。

我的示例查询:

GET /products/product/_search
{
  "size": 0,
  "aggs": {
    "myFancyFilter": {
      "filter": {
        "match_all": {}
      },
      "aggs": {
        "inner": {
          "terms": {
            "field": "Brand",
            "size": 3
          }
        }
      }
    }
  },
  "query": {
    "match_all": {}
  }
}

结果:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "failed": 0
  },
  "hits": {
    "total": 236952,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "myFancyFilter": {
      "doc_count": 236952,
      "inner": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 139267,
        "buckets": [
          {
            "key": "Brand1",
            "doc_count": 3144
          },
          {
            "key": "Brand2",
            "doc_count": 1759
          },
          {
            "key": "Brand3",
            "doc_count": 1737
          }
        ]
      }
    }
  }
}

它对我来说很完美。弹性根据doc_count对存储桶进行排序,但是我想在结果中操作存储桶顺序。例如,假设我有Brand5并且我想将其顺序递增到#2。我希望结果来自Brand1,Brand5和Brand3。

如果它不在aggregation中,而在query中,我可以使用function_score,但现在,我没有想法。有线索吗?

1 个答案:

答案 0 :(得分:1)

您要寻找的是定义您自己的排序定义,并将其应用于aggregation中的elasticsearch。我可以通过以下方式重命名聚合条件来提出解决方案:

  • Brand1a_Brand1
  • Brand5b_Brand5
  • Brand3c_Brand3

然后对术语进行排序,以便按字典顺序进行排序。

当然,这可能不是确切的解决方案,也不是最佳的解决方案,但是我认为这可以帮忙

下面是我使用的查询。请注意,我的字段名称是brand,它是multifield,我正在使用字段brand.keyword

POST testdataindex/_search
{  
   "size":0,
   "query":{  
      "match_all":{  

      }
   },
   "aggs":{  
      "myFancyFilter":{  
         "filter":{  
            "match_all":{  

            }
         },
         "aggs":{  
            "inner":{  
               "terms":{  
                  "script":{  
                     "lang":"painless",
                     "inline":"if(params.newNames.containsKey(doc['brand.keyword'].value)) { return params.newNames[doc['brand.keyword'].value];} return null;",
                     "params":{  
                        "newNames":{  
                           "Brand1":"a_Brand1",
                           "Brand5":"b_Brand5",
                           "Brand3":"c_Brand3"
                        }
                     }
                  },
                  "order":{  
                     "_term":"asc"
                  }
               }
            }
         }
      }
   }
}

我创建了一个样本数据,其商标名称为Brand1Brand3Brand5,并在结果下方显示。注意术语名称的变化。

{
  "took": 6,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 8,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "myFancyFilter": {
      "doc_count": 8,
      "inner": {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets": [
          {
            "key": "a_Brand1",
            "doc_count": 2
          },
          {
            "key": "b_Brand5",
            "doc_count": 4
          },
          {
            "key": "c_Brand3",
            "doc_count": 2
          }
        ]
      }
    }
  }
}

希望有帮助!