1

I am trying to do the following as described in the documentation (which is maybe outdated at present date).

https://www.elastic.co/guide/en/elasticsearch/guide/current/mapping.html

I will adapt the scenario described there to what I want to achieve.

Imagine that we have two types in our index: blog_t1 for blog posts about Topic 1, and blog_t2 for blog posts about Topic 2. Both types have a title field.

Then, I want to apply query boosting to the title field for blog_t1 only.

In previous versions of Elasticsearch, you could reference the field from the type by using blog_t1.title and blog_t2.title. So boosting one of them was as simple as blog_t1.title^2.

But since Elasticsearch 2.x, some old support for types have been removed (for good reasons, like removing ambiguity). Those changes are described here.

https://www.elastic.co/guide/en/elasticsearch/reference/current/breaking_20_mapping_changes.html

So my question is, how can I do that boosting for the title, just for the type blog_t1, and not blog_t2, with Elasticsearch 2.x, in a multi_match query?

The query would be something like this, but this obviously does not work as type.field is not a thing anymore.

GET /my_index/_search
{
  "query": {
    "multi_match": {
      "query": "Hello World",
      "fields": [
        "blog_t1.title^2",
        "blog_*.title",
        "author",
        "content"
      ]
    }
  }
} 

FYI, the only solution I found so far is to give the titles different names, like title_boosted for blog_t1 and just title for the others, which is problematic when making use of the information, as I can no longer use the "title" as a unique thing.

Thanks.

Pedro Lopez
  • 2,236
  • 2
  • 19
  • 27

1 Answers1

0

What about adding another "optional" constraint for the document type so docs matching it have more score (you can tune it with boosting) like:

{
  "query" : {
    "bool" : 
    {
      "must" : 
      [
        {"match" : {"title" : "Hello world"}}
      ],
      "should" : 
      [
        {"match" : {"_type" : "blog_t1"}}
      ]
    }
  }
}

Or with score functions:

{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "title": "Hello world"
        }
      },
      "boost_mode": "multiply",
      "functions": [
        {
          "filter": {
            "term": {
              "_type": "blog_t1"
            }
          },
          "weight": 2
        },
        {
          "filter": {
            "term": {
              "_type": "blog_t2"
            }
          },
          "weight": 3
        }
      ]
    }
  }
}
macebalp
  • 186
  • 9
  • Thanks for your answer, I see what you mean. That is an interesting suggestion indeed. But the thing is that I want to control the boosting with specific values. See for example that if I add a third field that needs a specific boosting, your solution would not work, e.g. blog_t1.title^3, blog_t2.title^2, blog_t3.title^1.5, blog_t*.title. – Pedro Lopez Feb 29 '16 at 22:09
  • Absolutely agree, maybe you could combine it with [score functions](https://www.elastic.co/guide/en/elasticsearch/guide/current/function-score-filters.html) with multiply score_mode? – macebalp Feb 29 '16 at 22:18
  • Regarding score functions check [this](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html) too. – macebalp Feb 29 '16 at 22:27
  • This is closer, but still does not work for me out of the box. Notice that I am using a multi_match query. That is because I am searching more fields than just the title, although the other fields might or might not be boosted. This totally works if I want to boost the whole type, but what if I want to boost only the title field in the type? How can I add to the filter something to specify one single field of the type blog_t1 or blog_t2 and not the other fields? I will edit my question to make clear that there are more fields than just the titles. Thanks a lot! – Pedro Lopez Mar 01 '16 at 11:16