Elasticsearch通过关键字搜索并提升

时间:2018-10-18 15:28:30

标签: elasticsearch spring-data spring-data-elasticsearch

我正在使用Spring Boot 2.0.5,Spring Data Elasticsearch 3.1.0和Elasticsearch 6.4.2

我已经为ElasticSearch加载了一组文章。对于每篇文章,我都有一个关键字字段,其中包含关键字的字符串列表,例如

"keywords": ["Football", "Barcelona", "Cristiano Ronaldo", "Real Madrid", "Zinedine Zidane"],

对于每个使用该应用程序的用户,他们可以使用权重因子指定其关键字首选项。

例如

User 1:
    keyword: Football, weight:3.0
    keyword: Tech, weight:1.0 
    keyword: Health, weight:2.0 

我想做的是根据关键字的偏好来查找文章,并根据其权重因子的偏好来显示它们(我认为这与弹性搜索的提升有关),并按照最新的文章时间进行排序。

这是我到目前为止(仅针对一个关键字):

 public Page<Article> getArticles(String keyword, float boost, Pageable pageable) {

        SearchQuery searchQuery = new NativeSearchQueryBuilder()
        .withQuery(QueryBuilders.matchQuery("keywords", keyword).boost(boost))
        .build();
        return articleRepository.search(searchQuery);
 }

由于用户可能有 n 个关键字首选项,因此我需要在上面的代码中进行哪些更改以支持此操作?

任何建议将不胜感激。

解决方案

好的,我enabled logging,所以我可以看到正在生成的弹性搜索查询。然后,我将getArticles方法更新为以下内容:

public Page<Article> getArticles(List<Keyword> keywords, Pageable pageable) {

    BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
    List<FilterFunctionBuilder> functions = new ArrayList<FilterFunctionBuilder>();

    for (Keyword keyword : keywords) {
        queryBuilder.should(QueryBuilders.termsQuery("keywords", keyword.getKeyword()));
        functions.add(new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                QueryBuilders.termQuery("keywords", keyword.getKeyword()),
                ScoreFunctionBuilders.weightFactorFunction(keyword.getWeight())));
    }
    FunctionScoreQueryBuilder functionScoreQueryBuilder = QueryBuilders.functionScoreQuery(queryBuilder,
            functions.toArray(new FunctionScoreQueryBuilder.FilterFunctionBuilder[functions.size()]));

    NativeSearchQueryBuilder searchQuery = new NativeSearchQueryBuilder();
    searchQuery.withQuery(functionScoreQueryBuilder);
    searchQuery.withPageable(pageable); 
    // searchQuery.withSort(SortBuilders.fieldSort("createdDate").order(SortOrder.DESC));
    return articleRepository.search(searchQuery.build());
}

这将产生以下弹性搜索查询:

{
  "from" : 0,
  "size" : 20,
  "query" : {
    "function_score" : {
      "query" : {
        "bool" : {
          "should" : [
            {
              "terms" : {
                "keywords" : [
                  "Football"
                ],
                "boost" : 1.0
              }
            },
            {
              "terms" : {
                "keywords" : [
                  "Tech"
                ],
                "boost" : 1.0
              }
            }
          ],
          "disable_coord" : false,
          "adjust_pure_negative" : true,
          "boost" : 1.0
        }
      },
      "functions" : [
        {
          "filter" : {
            "term" : {
              "keywords" : {
                "value" : "Football",
                "boost" : 1.0
              }
            }
          },
          "weight" : 3.0
        },
        {
          "filter" : {
            "term" : {
              "keywords" : {
                "value" : "Tech",
                "boost" : 1.0
              }
            }
          },
          "weight" : 1.0
        }
      ],
      "score_mode" : "multiply",
      "max_boost" : 3.4028235E38,
      "boost" : 1.0
    }
  },
  "version" : true
}

1 个答案:

答案 0 :(得分:0)

您正在寻找的是function_score查询。类似于

{
    "query": {
        "function_score": {
            "query": {
                "bool": {
                    "should": [
                        {"term":{"keyword":"Football"}},
                        {"term":{"keyword":"Tech"}},
                        {"term":{"keyword":"Health"}}
                    ]
                }
            },
            "functions": [
                {"filter":{"term":{"keyword":"Football"}},"weight": 3},
                {"filter":{"term":{"keyword":"Tech"}},"weight": 1},
                {"filter":{"term":{"keyword":"Health"}},"weight": 2}
            ]
        }
    }
}

请参见此处以获取API帮助https://www.elastic.co/guide/en/elasticsearch/client/java-api/current/java-compound-queries.html#java-query-dsl-function-score-query