Dennis
Dennis

Reputation: 936

elasticsearch: Add weight for each match of array

I want to add a weight for each match (instead of adding a weight once if one of those matched):

Having docs like this:

[{
    "username": "xyz",
    "categories": [
        {
            "category.id": 1
        },
        {
            "category.id": 2
        }
    ]
}, {
    "username": "xyz2",
    "categories": [
        {
            "category.id": 1
        }
    ]
}]

And currently, I have this query:

{
    "query": {
        "filtered": {
            "query": {
                "function_score": {
                    "query": {
                        "bool": {}
                    },
                    "score_mode": "sum",
                    "boost_mode": "sum",
                    "functions": [
                        {
                            "weight": 1.1,
                            "filter": {
                                "terms": {
                                    "category.id": [
                                        1,
                                        2
                                    ]
                                }
                            }
                        }
                    ]
                }
            },
            "filter": {
                "bool": {
                    "must_not": [
                        {
                            "terms": {
                                "_id": [
                                    8
                                ]
                            }
                        }
                    ]
                }
            }
        }
    },
    "from": 0,
    "size": 30
}

With this query, both entries would receive a single weight of 1.1, but I want the first entry to get 2 * 1.1 because 2 categories are matched. How could I achieve that?

EDIT: Sorry, I missed to add elastic search version. It's 1.7.2.

Upvotes: 1

Views: 1454

Answers (1)

Andrei Stefan
Andrei Stefan

Reputation: 52368

This might be a bit cumbersome, since for multiple IDs that query will need to have multiple statements, but I don't think there is any other way. Also, notice that your field referencing is not complete - it should be categories.category.id to be correct. Also, be careful when upgrading with dots in field names. This changed in some releases over time.

{
  "query": {
    "filtered": {
      "query": {
        "function_score": {
          "query": {
            "match_all": {}
          },
          "score_mode": "sum",
          "boost_mode": "sum",
          "functions": [
            {
              "weight": 1.1,
              "filter": {
                "term": {
                  "categories.category.id": 1
                }
              }
            },
            {
              "weight": 1.1,
              "filter": {
                "term": {
                  "categories.category.id": 2
                }
              }
            }
          ]
        }
      },
      "filter": {
        "bool": {
          "must_not": [
            {
              "terms": {
                "_id": [
                  8
                ]
              }
            }
          ]
        }
      }
    }
  },
  "from": 0,
  "size": 30
}

Upvotes: 1

Related Questions