Query to get results based on priority of fields

Hi,

I have following mapping :

> PUT products
> {
> 	"mappings" : {
> 		"properties" : {
> 			"item_name" : {"type" : "keyword"},
> 			"catalog_name" : {"type" : "keyword"},
> 			"group" : {"type" : "keyword"},
> 			"location" : {"type" : "keyword"},
> 			"price" : {"type" : "double"}
> 		}
> 	}
> }

and below are the docs of the products index

> POST /products/_bulk
> {"index":{}}
> {"item_name":"item1", "catalog" :  "catalog1", "location" :  "india", "price": 100}
> {"index":{}}
> {"item_name":"item2", "catalog" :  "catalog1", "location" :  "india", "price": 200}
> {"index":{}}
> {"item_name":"item1", "catalog" :  "catalog1", "group" :  "gold", "price": 90}

Item  | Catalog | group | location | price
Item1 | 1.0 	| -     | india	   | 100
Item2 | 1.0 	| - 	| india    |  200
Item1 | 2.0     | gold  | - 	   | 90

following is my query:

GET /products/_search
{
  "query": {"bool": {"must": [
    {"boosting": 
      {
      "positive": {"term": {
        "group": {
          "value": "gold"
        }
        }},
      "negative": {"term": {
        "location": {
          "value": "india"
        }
      }},
      "negative_boost": 0.5
    }}
  ]}}
}

the above search query is resulting in:

Item  | Catalog | group | location | price
Item1 | 2.0 	| gold	| - 	   | 90

but what I want is:

Item  | Catalog | group | location | price
Item2 | 1.0 	| - 	| india    | 200
Item1 | 2.0 	| gold	| - 	   | 90

If the user belongs to gold group and lives in india, priority should be given to gold group item1 and then location.

Can anyone please let me know how to write a query for such a scenario? Thanks in advance.

Hi @dawood_abdullah !!

Provides more details like some docs, mapping and search term. That way it will be easier to help.

Hi andre, I have updated the question. Thank you.

Do you see about Function Score?

Your query can be like this:

GET products/_search
{
  "collapse": {
    "field": "item_name"
  },
  "query": {
    "function_score": {
      "query": {
        "match_all": {}
      },
      "functions": [
        {
          "filter": {
            "term": {
              "group": "gold"
            }
          },
          "weight": 50
        },
        {
          "filter": {
            "term": {
              "location": "india"
            }
          },
          "weight": 10
        }
      ]
    }
  }
}
1 Like

function_score query is resulting in all three records:

Item  | Catalog | group | location | price
Item1 | 1.0 	| -     | india	   | 100
Item2 | 1.0 	| - 	| india    |  200
Item1 | 2.0     | gold  | - 	   | 90

instead we need only two records in this case, as Item1 in gold group is of priority than item1 of india location.

Item  | Catalog | group | location | price
Item2 | 1.0 	| - 	| india    |  200
Item1 | 2.0     | gold  | - 	   | 90

I think it's kind of complicated for you to fetch only the Item2 and Item1 docs. I don't see an exclusion criteria for this doc:

Item | Catalog | group | location | price
Item1 | 1.0 | - | india | 100

The query I sent only impact the score of the documents, the query is not filtering documents. With functionScore, you must find the best way to make the documents you want more relevant.

Thank you for your quick responses Andre.

Is there a way that I can say in the query that Item1 document of india and Item1 document of group are similar, and priortise item1 of group over item1 of india in the result?

Maybe you can give a greater weight to the docs that have the "groups" field and/or that are of the "gold" type.

And this case, wich doc must be priority?

Item  | Catalog | group | location | price
Item1 | 1.0 	| -     | india	   | 100
Item2 | 1.0 	| - 	| india    |  200
Item  | Catalog | group | location | price
Item1 | 1.0 	| -     | india	   | 100
Item2 | 1.0 	| - 	| india    |  200

These are different items (item1, item2), so both will be returned as part of the result.

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.