0

For documents like

{
"_id" : "abc123",
"_score" : 3.7613528,
"_source" : {
    "id" : "abc123",
    "pricePeriods" : [{
            "periodTo" : "2016-01-02",
            "eur" : 1036,
            "gbp" : 782,
            "dkk" : 6880,
            "sek" : 9025,
            "periodFrom" : "2015-12-26",
            "nok" : 8065
        }, {
            "periodTo" : "2016-06-18",
            "eur" : 671,
            "gbp" : 457,
            "dkk" : 4625,
            "sek" : 5725,
            "periodFrom" : "2016-01-02",
            "nok" : 5430
        }       ]

 }
}

I would like to have a gauss decay function score on the prices.

I have tried like this

"query" : {
    "function_score" : {
        "functions" : [{
                "gauss" : {
                    "pricePeriods.dkk" : {
                        "origin" : "2500",
                        "scale" : "2500",
                        "decay" : 0.8

                    }
                },
                "filter" : {
                    "nested" : {
                        "filter" : {
                            "range" : {
                                "pricePeriods.periodTo" : {
                                    "gte" : "2016-03-17T00:00:00.000"
                                }
                            }

                        },
                        "path" : "pricePeriods"

                    }
                }
            }
            ]

and it seems that the filter finds the prices I want to make a gauss on, but the resulting score is always 1.

Explain says

{ "value": 1,
  "description": "min of:",
   "details": [
    {
         "value": 1,
         "description": "function score, score mode [multiply]",
          "details": [
                    {
              "value": 1,
               "description": "function score, product of:",
                 "details": [
                  {
                    "value": 1,
                       "description": "match filter: ToParentBlockJoinQuery (+ConstantScore(pricePeriods.periodTo:[[32 30 31 36 2d 30 33 2d 31 37 54 30 30 3a 30 30 3a 30 30 2e 30 30 30] TO *]) #QueryWrapperFilter(_type:__pricePeriods))",
                                         "details": []
                                      },
                                      {
                                         "value": 1,
                                         "description": "Function for field pricePeriods.dkk:",
                                         "details": [
                                            {
                                               "value": 1,
                                               "description": "exp(-0.5*pow(MIN[0.0],2.0)/1.4004437867889222E7)",
                                               "details": []
                                            }
                                         ]
                                      }
                                   ]
                                }
                             ]
                          }

I can see here that gauss apparently returns 1 when it can't find the field. But the questions is why it can't find the field in nested docs and how to ix that.

SuperStormer
  • 4,997
  • 5
  • 25
  • 35
ClausP
  • 1
  • 4

1 Answers1

0

The reason gauss function is returning 1 is because as you said it can't find the field as it is nested, you basically need to wrap your whole function_score query into nested query

{
  "query": {
    "nested": {
      "path": "pricePeriods",
      "query": {
        "function_score": {
          "functions": [
            {
              "gauss": {
                "pricePeriods.dkk": {
                  "origin": "2500",
                  "scale": "2500",
                  "decay": 0.8
                }
              },
              "filter": {
                "range": {
                  "pricePeriods.periodTo": {
                    "gte": "2016-03-17T00:00:00.000"
                  }
                }
              }
            }
          ]
        }
      }
    }
  }
}

Does this help?

ChintanShah25
  • 12,366
  • 3
  • 43
  • 44
  • Thanks, but there are still two problems with it. 1: It still returns score 1 for all results, no matter if they have prices or not. [link](http://screencast.com/t/nDE7g6tLYV) 2: I can't add other functions for the parent. The full query is a quite complex one with scores for many different fields. But I can't figure out how to add both nested and top level function scores. – ClausP Dec 26 '15 at 09:58
  • I created one test index and It worked, It gave score of 1 to only those documents that did not match the condition. What version of ES you are using? – ChintanShah25 Dec 27 '15 at 01:51
  • Thanks. Seems to be working now. I had forgotten to add a weight to the function, so all docs matching the gauss filter was sorted below 1. By adding a wight, it seems to be scored much better now. I use version 2.1.1 and 1.7 – ClausP Dec 28 '15 at 10:23