Function score and nested document


(Silvestre Losada) #1

HI,

I have a nested object on my mappings with multiple values. Every user has a set of capacities each capacity has a number of points that describes the level of the user in that capacity.

{
	"userId": "1",
	"usertype": 2,
	"capacities": [{
		"id": "capacity1",
		"score": 20
	}, {
		"id": "capacity3",
		"score": 0
	}, {
		"id": "capacity2",
		"score": 40
	}]
},
{
	"userId": "2",
	"usertype": 2,
	"capacities": [{
		"id": "capacity1",
		"score": 20
	}, {
		"id": "capacity4",
		"score": 40
	}, {
		"id": "capacity2",
		"score": 10
	}]

}

I want to create a query that rank the result using a set of capacities, I'm trying to use function score with field value factor.

{
    "query": {
        "function_score": {
            "query": {
                "bool": {
                    "should": [
                        {
                            "nested": {
                                "path": "capacities",
                                "query": {
                                    "function_score": {
                                        "query": {
                                            "term": {
                                                "capacities.id": {
                                                    "value": "capacity1"
                                                },
                                                "boost": 1
                                            }
                                        },
                                        "functions": [
                                            {
                                                "field_value_factor": {
                                                    "field": "capacities.score",
                                                    "modifier": "log1p",
                                                    "factor": 1
                                                }
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    ]
                }
            }
        }
    }
}

The matched nested document for capacity1 has a score of 20, I expect to get is a ES score which is log(21), but I'm not getting such value. here is my explain

"_explanation": {
	"value": 6.8698506,
	"description": "sum of:",
	"details": [{
		"value": 6.8698506,
		"description": "sum of:",
		"details": [{
			"value": 6.8698506,
			"description": "Score based on child doc range from 193 to 221",
			"details": []
		}]
	}]
}

(Lee Hinman) #2

I believe you are missing score_mode and boost_mode for your
queries, here is an example that works for me:

PUT /test
{
  "mappings": {
    "user": {
      "properties": {
        "capacities": {
          "type": "nested",
          "properties": {
            "score": {
              "type": "integer"
            },
            "id": {
              "type": "keyword"
            }
          }
        }
      }
    }
  }
}

POST /test/user/1
{
  "userId": "1",
  "usertype": 2,
  "capacities": [{
    "id": "capacity1",
    "score": 20
  }, {
    "id": "capacity3",
    "score": 0
  }, {
    "id": "capacity2",
    "score": 40
  }]
}

POST /test/user/2
{
  "userId": "2",
  "usertype": 2,
  "capacities": [{
    "id": "capacity1",
    "score": 20
  }, {
    "id": "capacity4",
    "score": 40
  }, {
    "id": "capacity2",
    "score": 10
  }]
}

POST /test/user/2/_explain?pretty
{
  "query": {
    "nested": {
      "path": "capacities",
      "score_mode": "sum",
      "query": {
        "function_score": {
          "query": {
            "bool": {
              "filter": [
                {
                  "term": {
                    "capacities.id": {
                      "value": "capacity1"
                    }
                  }
                }
              ]
            }
          },
          "boost_mode": "replace",
          "functions": [
            {
              "field_value_factor": {
                "field": "capacities.score",
                "modifier": "log1p",
                "factor": 1
              }
            }
          ]
        }
      }
    }
  }
}

And here's the output from the explain, where you can see the log(21) as
1.3222193:

{
  "_index" : "test",
  "_type" : "user",
  "_id" : "2",
  "matched" : true,
  "explanation" : {
    "value" : 1.3222193,
    "description" : "sum of:",
    "details" : [
      {
        "value" : 1.3222193,
        "description" : "Score based on 1 child docs in range from 4 to 6, best match:",
        "details" : [
          {
            "value" : 1.3222193,
            "description" : "sum of:",
            "details" : [
              {
                "value" : 1.3222193,
                "description" : "min of:",
                "details" : [
                  {
                    "value" : 1.3222193,
                    "description" : "field value function: log1p(doc['capacities.score'].value * factor=1.0)",
                    "details" : [ ]
                  },
                  {
                    "value" : 3.4028235E38,
                    "description" : "maxBoost",
                    "details" : [ ]
                  }
                ]
              },
              {
                "value" : 0.0,
                "description" : "match on required clause, product of:",
                "details" : [
                  {
                    "value" : 0.0,
                    "description" : "# clause",
                    "details" : [ ]
                  },
                  {
                    "value" : 1.0,
                    "description" : "_type:__capacities, product of:",
                    "details" : [
                      {
                        "value" : 1.0,
                        "description" : "boost",
                        "details" : [ ]
                      },
                      {
                        "value" : 1.0,
                        "description" : "queryNorm",
                        "details" : [ ]
                      }
                    ]
                  }
                ]
              }
            ]
          }
        ]
      },
      ... etc ...
    ]
  }
}

(Silvestre Losada) #3

Thanks, I played with score_mode replace is the piece I need.

Thanks


(system) #4

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