Условная оценка Elasticsearch в java - PullRequest
0 голосов
/ 13 июля 2020

Я новичок в Elasti c Search, и я хотел спросить, как я могу повысить определенные результаты запроса, основанного на некотором условном выражении. В частности, элементы в Elasti c Search имеют следующий формат:

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

Я хочу, чтобы оценка некоторых элементов (с "brand" = "nike") была ниже, чем у других брендов. Есть ли способ сделать это с помощью классов QueryBuilders, которые есть в java для поиска elasti c?

Ответы [ 2 ]

0 голосов
/ 11 августа 2020

Чтобы увеличить определенное значение определенного поля (или наоборот), вы можете использовать Function score query. Проверьте официальный документ Здесь .

Позвольте мне показать вам пример:

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

Этот запрос ссылается на то, что «Я ищу документы, соответствующие ключевому слову shoes в поле name и отсортируйте в обратном порядке _score. Однако если в документах есть термин nike в поле maker, я надеюсь, что оценка будет равна 0 (так как умножение любого числа на 0 равно 0). "

В 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);

Есть несколько boost_mode, таких как умножение (по умолчанию), замена, сумма, среднее, максимальное, минимальное. Таким образом, вы можете применить этот код для своих нужд.

Надеюсь, это именно то, что вы искали.

0 голосов
/ 13 июля 2020

Запрос на повышение может решить проблему. В качестве альтернативы вы также можете использовать запросы function_score для большей гибкости.

Пример с повышающим запросом.

(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) Запрос с отрицательным усилением для 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"
        }
      }
    ]
  }
}
...