1

As part of a more complex query there is a should condition on a field:

boolQuery.should(QueryBuilders.matchQuery("myOptionalField", myValue));

This way the records having the field myOptionalField matching the value myValue get a scoring bonus. That's good. Those fields having a different value don't get the bonus.

My new requirement is to also give some points to the records that are missing this field. It shall be less than the records matching myValue, but more than those having a non-matching value.

I find this a pretty standard requirement but can't find the solution. There is elasticsearch bool query combine must with OR but it's different.

According to the documentation, in ES the "should" is the OR. So I'm trying with:

boolQuery.should(new BoolQueryBuilder()
  .should(QueryBuilders.matchQuery("myOptionalField", myValue))
  .should(new BoolQueryBuilder().mustNot(QueryBuilders.existsQuery("myOptionalField")))
);

Now this changes (screws up) the scoring. Obviously a record can't match both of the nested "should" conditions.

As for the scoring, I can add .boost() in various places, but nothing works in my favor. Here are all the possible places that accept a scoring definition (see .boost(0.2f)):

boolQuery.should(new BoolQueryBuilder()
  .should(QueryBuilders.matchQuery("myOptionalField", myValue).boost(0.2f)).boost(0.2f)
  .should(new BoolQueryBuilder().mustNot(QueryBuilders.existsQuery("myOptionalField")).boost(0.2f)).boost(0.2f)
);

The inner .boost(0.2f) calls are ignored. The outer ones are not, but I believe the boosts are applied to the outer BoolQueryBuilder() and thus they override each other. Anyway, the problem is that any boost definition makes the records not having the myOptionalField get a higher score than those matching the myValue.

The 2 questions are:

1) Is my syntax with the nested "should" the way to write this in ES?

2) How do I boost the scores to have 1st = match query, 2nd = field absent, 3rd = don't match query?

Community
  • 1
  • 1
Fabian Kessler
  • 744
  • 10
  • 12
  • I think [explain API](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-explain.html) might help you figure out what's happening with scoring and boosting. You can also use `_search?explain` to get score explanation per hit which is docummented [here](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html). – slawek Jan 23 '17 at 17:27

0 Answers0