简体   繁体   English

java 中的 Elasticsearch 条件评分

[英]Elasticsearch conditional scoring in java

I am new to Elastic Search and I wanted to ask how can I boost certain results from a query based on some conditional.我是 Elastic Search 的新手,我想问一下如何根据某些条件从查询中提升某些结果。 Specifically, the items in Elastic Search are of the following format:具体来说,Elastic Search 中的项目具有以下格式:

"name":"item1",
"desc":"desc1",
"brand":"brandname"

I want to make the score of certain items (those with "brand" = "nike" ) have lower score than the other brands.我想让某些商品(带有"brand" = "nike"的商品)的得分低于其他品牌。 Is there a way to do that with the QueryBuilders classes that java has for elastic search?有没有办法使用 java 用于弹性搜索的 QueryBuilders 类来做到这一点?

Boosting query might be able to solve the problem. 提升查询可能能够解决问题。 Alternatively, you can also use function_score queries for more flexibility.或者,您也可以使用function_score 查询以获得更大的灵活性。

Example with boosting query.提升查询的示例。

(1) Index few documents (1) 索引少数文档

curl -XPOST localhost:9200/idx/doc/1 -d '{"content": "foo"}' --header "Content-type:application/json" 
curl -XPOST localhost:9200/idx/doc/2 -d '{"content": "bar"}' --header "Content-type:application/json" 
curl -XPOST localhost:9200/idx/doc/3 -d '{"content": "foo fred bar"}' --header "Content-type:application/json" 

(2) Query with a negative boost for bar to reduce score for bar (2) 对bar进行负提升的查询以降低bar的分数

 curl -XPOST localhost:9200/idx/_search?pretty -d '{
  "query": {
    "boosting": {
      "positive": {
        "match": {
          "content": "foo bar fred"
        }
      },
      "negative": {
        "match": {
          "content": "bar"
        }
      } , "negative_boost": 0.001
    }
  }
}' --header "Content-type:application/json" 


{
  "took" : 59,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 3,
      "relation" : "eq"
    },
    "max_score" : 0.5619609,
    "hits" : [
      {
        "_index" : "idx",
        "_type" : "doc",
        "_id" : "1",
        "_score" : 0.5619609,
        "_source" : {
          "content" : "foo"
        }
      },
      {
        "_index" : "idx",
        "_type" : "doc",
        "_id" : "3",
        "_score" : 0.0014472058,
        "_source" : {
          "content" : "foo fred bar"
        }
      },
      {
        "_index" : "idx",
        "_type" : "doc",
        "_id" : "2",
        "_score" : 5.619609E-4,
        "_source" : {
          "content" : "bar"
        }
      }
    ]
  }
}

To boost a certain value of a certain field (or vice versa), you can use a Function score query .要提升某个字段的某个值(反之亦然),您可以使用Function score query Check the official document Here . 在这里查看官方文档

Let me show you an example:让我给你看一个例子:

    POST /goods/_search
    {
      "query": {
        "function_score": {
          "query": {
            "match": {
              "name": "shoes"
            }
          },
          "functions": [
            {
              "filter": {
                "term": {
                  "maker": "nike"
                }
              },
              "weight": 0
            }
          ],
          "boost_mode": "multiply"
        }
      },
      "sort": [
        {
          "_score": {
            "order": "desc"
          }
        }
      ]
    }

This query refers that "I'm looking for documents which match a keyword shoes in a name field and sort in reverse order of _score . If documents have a term nike in a maker field, however, I hope that the score is 0(cause multiplying any number by 0 equals 0)."此查询是指“我正在查找与name字段中的关键字shoes匹配的文档,并以_score的相反顺序排序。但是,如果文档在maker字段中有术语nike ,我希望分数为 0(因为任何数乘以 0 等于 0)。”

In Java code,在 Java 代码中,

    String indexName = "goods"
    String nameField = "name";
    String makerField = "maker";

    String keyword = "shoes";
    String unnecessaryMaker = "nike";
    
    MatchQueryBuilder matchQueryBuilder = new MatchQueryBuilder(nameField, keyword);
    FilterFunctionBuilder[] filterFunctions = {
        new FunctionScoreQueryBuilder.FilterFunctionBuilder(
            QueryBuilders.termQuery(makerField, unnecessaryMaker),
            ScoreFunctionBuilders.weightFactorFunction(0)
        )
    };
            
    FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(matchQueryBuilder, filterFunctions);
    functionScoreQueryBuilder.boostMode(CombineFunction.MULTIPLY);

    SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
    searchSourceBuilder.query(functionScoreQueryBuilder);
        
    SearchRequest request = new SearchRequest();
    request.indices(indexName);
    request.source(searchSourceBuilder);

There are several boost_mode such as multiply(default), replace, sum, avg, max, min.有多种boost_mode ,例如 multiply(default)、replace、sum、avg、max、min。 So you can apply this code to your needs.因此,您可以将此代码应用于您的需求。

Hope this is what you were looking for.希望这就是你要找的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM