# Nested value on function score

**URL:** <https://discuss.elastic.co/t/nested-value-on-function-score/29935>\
**Category:** Elasticsearch\
**Created:** [September 24, 2015, 5:22pm UTC](https://discuss.elastic.co/t/nested-value-on-function-score/29935 "2015-09-24T17:22:01Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![cldsnchz](https://avatars.discourse-cdn.com/v4/letter/c/278dde/32.png) [@cldsnchz](https://discuss.elastic.co/u/cldsnchz)\
**Post date:** [September 24, 2015, 5:22pm UTC](https://discuss.elastic.co/t/nested-value-on-function-score/29935/1 "2015-09-24T17:22:01Z")

</div>

Hi, I have a document with a nested array, and I'm trying to get a nested value in a funtion score but I can't (I always get 0).

For example having the following mapping:

```
{
  "mapping":{
    "movie":{
      "properties":{
        "title":{ "type":"string" },
        "reviews":{
          "type":"nested",
          "properties":{
            "rating":{ "type":"long" },
            "userId":{ "type":"string", "index":"not_analyzed" }
          }
        }
      }
    }
  }
}

```

I want to set the score with the rating of a particular user. To do that I execute this query:

```
{
  "query" : {
    "function_score" : {
      "functions" : [ {
        "filter" : {
          "nested" : {
            "filter" : { "term" : { "userId" : "1" } },
            "path" : "reviews"
          }
        },
        "script_score" : {
          "script" : "doc['reviews.rating'].value"
        }
      } ]
    }
  }
}

```

But that query returns \_score = 0 for all records.

Is there a way to score based on a nested value?  
(I'm using a function score instead of a nested sorting because I have several score functions and I took the max)

Thanks, Claudio.

Here there are some example documents:

```
{
   "title": "The Godfather",
   "reviews": [
      { "userId": "1", "rating": "5" },
      { "userId": "2", "rating": "4" }
   ]
}

{
   "title": "Rocky",
   "reviews": [
      { "userId": "1", "rating": "3" },
      { "userId": "2", "rating": "5" }
   ]
}
```

---

<div class="post-metadata">

**Author:** ![msimos](https://avatars.discourse-cdn.com/v4/letter/m/bb73d2/32.png) [@msimos](https://discuss.elastic.co/u/msimos)\
**Post date:** [September 24, 2015, 8:43pm UTC](https://discuss.elastic.co/t/nested-value-on-function-score/29935/2 "2015-09-24T20:43:28Z")

</div>

You'd want to do something like this and you may want to consider using field value factor:

[https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-field-value-factor](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-field-value-factor)

```auto
{
  "query": {
    "filtered": {
      "query": {
        "nested": {
          "path": "reviews",
          "query": {
            "function_score": {
              "query": {
                "term": {
                  "reviews.userId": {
                    "value": "1"
                  }
                }
              },
              "functions": [
                {
                  "field_value_factor": {
                    "field": "reviews.rating"
                  }
                }
              ]
            }
          }
        }
      }
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![cldsnchz](https://avatars.discourse-cdn.com/v4/letter/c/278dde/32.png) [@cldsnchz](https://discuss.elastic.co/u/cldsnchz)\
**Post date:** [September 25, 2015, 2:55am UTC](https://discuss.elastic.co/t/nested-value-on-function-score/29935/3 "2015-09-25T02:55:25Z")

</div>

Thanks Mike, Your query works fine

However I'm not sure how to add this in a bigger function\_score query.

I mean I have a function\_score query which wraps the main query (a filtered one) and have several functions with a max score\_mode.  
Ideally I would like to add the nested value score as a new function. But it seems that to access to tracking.rating in the function, the function\_score has to be in the context of a nested query to work.

So basically the question having a function\_score query, is there a way to add a new function which access to tracking.rating of a particular user, without putting the whole query inside a nested query?

---

<div class="post-metadata">

**Author:** ![cldsnchz](https://avatars.discourse-cdn.com/v4/letter/c/278dde/32.png) [@cldsnchz](https://discuss.elastic.co/u/cldsnchz)\
**Post date:** [September 27, 2015, 1:11am UTC](https://discuss.elastic.co/t/nested-value-on-function-score/29935/4 "2015-09-27T01:11:30Z")

</div>

I was able to add this query into a bigger one using the a DisMax query: ([https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-dis-max-query.html](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-dis-max-query.html))

Thanks, Claudio.

---

<div class="post-metadata">

**Author:** ![VasekPurchart](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/vasekpurchart/32/7046_2.png) [@VasekPurchart](https://discuss.elastic.co/u/VasekPurchart)\
**Post date:** [January 8, 2016, 1:12pm UTC](https://discuss.elastic.co/t/nested-value-on-function-score/29935/5 "2016-01-08T13:12:33Z")

</div>

Hi,

thanks for this example, is there some way to reference the nested field inside the function itself?  
Because when I wrap the whole function in a nested query like this I start getting errors about matching parent documents `child query must only match non-parent docs, but parent docID=2147483647 matched childScorer=class org.apache.lucene.search.ConjunctionScorer"`.

If I include the nested query only to the filter part, where it works correctly (I have tried replacing `field_value_factor` with a simple `weight` function), then I start getting missing field errors `Missing value for field [fieldName]`, which makes no sense to me, because if the filter on the function matches only the correct documents, then the value must be always present.

Please can you elaborate on this an possible syntax options?

Thanks in advance!

---

<div class="post-metadata">

**Author:** ![djudd](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/djudd/32/9206_2.png) [@djudd](https://discuss.elastic.co/u/djudd)\
**Post date:** [April 15, 2016, 10:39pm UTC](https://discuss.elastic.co/t/nested-value-on-function-score/29935/6 "2016-04-15T22:39:30Z")

</div>

The syntax @msimos describes doesn't work for me with Elasticsearch 2.2. Should it? The "missing" fallback is always used, even when the score field is present in the \_source returned.

Example query:

```
{
  "query": {
    "function_score": {
      "functions": [
        {
          "field_value_factor": {
            "field": "authors.interestingness",
            "factor": 1,
            "missing": 1
          }
        }
      ],
      "boost_mode": "multiply",
      "query": {
        "filtered": {
          "query": {
            "bool": {
              "should": [
                {
                  "query_string": {
                    "query": "Open Access",
                    "fields": [
                      "title"
                    ],
                    "boost": 1000,
                    "default_operator": "AND",
                    "allow_leading_wildcard": false
                  }
                },
                {
                  "match": {
                    "title": {
                      "query": "Open Access",
                      "type": "phrase",
                      "boost": 1000000
                    }
                  }
                },
              },
          },
          "filter": {
            "and": [
              {
                "not": {
                  "filter": {
                    "or": [
                      {
                        "term": {
                          "spam": true
                        }
                      }
                    ]
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  "_source": true,
  "explain": true
}

```

Schema, with some irrelevant fields snipped:

```
{
  "works-advanced-production-4": {
    "aliases": {
      "works-advanced-production": {}
    },
    "mappings": {
      "work": {
        "_all": {
          "enabled": false
        },
        "properties": {
          "attachments": {
            "type": "nested",
            "properties": {
              "created_at": {
                "type": "date",
                "format": "strict_date_optional_time||epoch_millis"
              },
              "id": {
                "type": "integer"
              },
              "text": {
                "type": "string"
              }
            }
          },
          "authors": {
            "type": "nested",
            "properties": {
              "id": {
                "type": "integer"
              },
              "interestingness": {
                "type": "float"
              },
              "name": {
                "type": "string",
                "index": "not_analyzed"
              }
            }
          },
          "id": {
            "type": "integer"
          },
          "index_error": {
            "type": "boolean"
          },
          "metadata": {
            "properties": {
              "abstract": {
                "type": "string"
              },
            },
          },
          "spam": {
            "type": "boolean"
          },
          "title": {
            "type": "string"
          },
          "views": {
            "type": "integer"
          }
        }
      }
    },
    "settings": {
      "index": {
        "number_of_replicas": "2",
        "number_of_shards": "6",
      }
    },
    "warmers": {}
  }
}
```

---

<div class="post-metadata">

**Author:** ![nate00](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/nate00/32/14608_2.png) [@nate00](https://discuss.elastic.co/u/nate00)\
**Post date:** [January 16, 2017, 6:39pm UTC](https://discuss.elastic.co/t/nested-value-on-function-score/29935/7 "2017-01-16T18:39:50Z")

</div>

@djudd the query you posted doesn't work because the `function_score` query doesn't have a parent `nested` query. You'd have to add a parent `nested` query like so:

```auto
{
  "query": {
    "nested": {
      "path": "authors",
      "query": {
        "function_score": {
          "functions": [
            {
              "field_value_factor": {
                "field": "authors.interestingness",
                "factor": 1,
                "missing": 1
              }
            }
          ],
          "boost_mode": "multiply",
          "query": {
            "filtered": {
              ... same as before ...
            }
          }
        }
      }
    }
  }
}

```

Unfortunately, even that won't work because your `filtered` query (which matches against non-nested fields) will break once it's inside the `nested` context.

The desired behavior is:

1. Run a query against non-nested fields.
2. Multiply the score from that query by a nested field's value.

As far as I can tell, there's no way to implement that desired behavior until [this feature request](https://github.com/elastic/elasticsearch/issues/17116) is completed.

(Like it says in that issue, if you wanted to add scores instead of multiply, you could use a `bool` query. And if you wanted the max, you could use `dis_max`.)

---

<div class="post-metadata">

**Author:** ![besson](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/besson/32/15808_2.png) [@besson](https://discuss.elastic.co/u/besson)\
**Post date:** [March 9, 2017, 10:36am UTC](https://discuss.elastic.co/t/nested-value-on-function-score/29935/8 "2017-03-09T10:36:51Z")

</div>

Hello, I have a related question that I couldn't get from the previous discussion.  
I want to boost by a nested object field but a filtered one. Let's say I have this documents:

```
POST /test/doc/1
{
  "title": "doc 1",
  "queries": 
    [
      {
        "hash": "102a",
         "value": 0.9
      },
      {
        "hash": "101a",
       "value": 0.9
      }
    ]
}

POST /test/doc/2
{
  "title": "doc 2",
  "queries": 
    [
      {
        "hash": "102a",
         "value": 1.0
      },
      {
        "hash": "101a",
       "value": 0.8
      }
    ]
}

POST /test/doc/3
{
  "title": "doc 3",
  "queries": 
    [
      {
        "hash": "103a",
         "value": 0.9
      },
      {
        "hash": "101a",
       "value": 0.3
      }
    ]
}

```

I want to match all documents but boost those ones that have a specific hash value:

```
GET /test/doc/_search
{
    "query": {
      "nested": {
        "path": "queries",
        "query": {
          "function_score": {
            "query": { "match_all": {} },
            "functions": [
              {
                "field_value_factor": {
                  "field": "queries.value",
                  "missing": 0
                },
                "filter": {
                    "match": {"queries.hash": "102a"}
                }
              }
            ]
          }
        }
      }
    }
}

```

With this query I expected doc 2, doc1 and doc 3 were returned in this order, given I am using the queries.value for the hash value 102a. However, the result is not that. I have a different order and a constant score of 1 for each document.

Could you please point any mistakes in my query or tell me if is not possible to have this with nested documents in function scores.

thank you!

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/elastic/original/3X/1/a/1ac57faf039f6b580b3f104ef42a2a89e41014de.png) [@system](https://discuss.elastic.co/u/system)\
**Post date:** [July 5, 2017, 10:02pm UTC](https://discuss.elastic.co/t/nested-value-on-function-score/29935/9 "2017-07-05T22:02:23Z")

</div>


