0

Continuation of the question Elasticsearch: Influence scoring with custom score field in document pt.2

It all works ok as @Joanna's answer. I just want to add decay function to the query:

{
  "query": {
    "function_score": {
        "query": {
            "bool": {
                "should": [{
                    "nested": {
                      "path": "tags",
                      "score_mode": "sum",
                      "query": {
                        "function_score": {
                          "query": {
                            "match": {
                              "tags.tag": "landscape"
                            }
                          },
                          "field_value_factor": {
                            "field": "tags.confidence",
                            "factor": 1,
                            "missing": 0
                          }
                        }
                      }
                    }
                }]
            }
        },
        "field_value_factor": {
            "field": "boost_multiplier",
            "factor": 1,
            "missing": 0
        }
      }
    }
} 

based on the created_at field of the document:

{
  "created_at" : "2017-07-31T20:30:14-04:00",
  "description" : null,
  "height" : 3213,
  "id" : "1",
  "tags" : [
    {
      "confidence" : 65.48948436785749,
      "tag" : "beach"
    },
    {
      "confidence" : 57.31950504425406,
      "tag" : "sea"
    },
    {
      "confidence" : 43.58207236617374,
      "tag" : "coast"
    },
    {
      "confidence" : 35.6857910950816,
      "tag" : "sand"
    },
    {
      "confidence" : 33.660057321079655,
      "tag" : "landscape"
    },
    {
      "confidence" : 32.53252312423727,
      "tag" : "sky"
    }
  ],
  "width" : 5712,
  "color" : "#0C0A07",
  "boost_multiplier" : 1
}

I found this in the documentation: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-decay

I tried to add the gauss function as shown in the example in the documentation as sibling to inner "field_value_factor", and it gives error saying "failed to parse [function_score] query. already found function [field_value_factor], now encountering [gauss]. use [functions] array if you want to define several functions.".

Then I put both "field_value_factor", and "gauss" under functions array inside inner "query", this time I get error saying "failed to parse [START_OBJECT]. malformed query, expected a [VALUE_STRING] while parsing functions but got a [function_score] instead".

Simply I can't find where to put the "gauss" function in the query to use decaying based on created_at field.

UPDATE I also tried the below query:

{
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "should": [{
            "nested": {
              "path": "tags",
              "score_mode": "sum",
              "query": {
                "function_score": {
                  "query": {
                    "match": {
                      "tags.tag": "landscape city"
                    }
                  },
                  "field_value_factor": {
                    "field": "tags.confidence",
                    "factor": 5,
                    "missing": 0
                  }
                }
              }
            }
          }]
        }
      },
      "functions": [
        {
          "decay": {
            "gauss": {
              "created_at": {
                "origin": "2013-09-17",
                "scale": "10d",
                "offset": "5d",
                "decay": 0.5
              }
            }
          }
        },
        {
          "field_value_factor": {
            "field": "boost_multiplier",
            "factor": 1,
            "missing": 0
          }
        }
      ]
    }
  }
}

This time it gives error saying "no [query] registered for [decay]".

Any help?

UPDATE-2 The following query works:

{
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "should": [{
            "nested": {
              "path": "tags",
              "score_mode": "sum",
              "query": {
                "function_score": {
                  "query": {
                    "match": {
                      "tags.tag": "landscape city"
                    }
                  },
                  "field_value_factor": {
                    "field": "tags.confidence",
                    "factor": 5,
                    "missing": 0
                  }
                }
              }
            }
          }]
        }
      },
      "functions": [
        {
          "field_value_factor": {
            "field": "boost_multiplier",
            "factor": 1,
            "missing": 0
          }
        },
        {
          "gauss": {
            "created_at": {
              "scale": "365d",
              "offset": "5d",
              "decay" : 0.5
            }
          }
        }
      ]
    }
  }
}

Works meaning it doesn't give error, but I don't get the result I expected. I simply want to give boost to the recent documents over the older ones. Any help how to achieve it?

Ahmet Cetin
  • 3,683
  • 3
  • 25
  • 34

1 Answers1

0

This query worked:

{
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "should": [{
            "nested": {
              "path": "tags",
              "score_mode": "sum",
              "query": {
                "function_score": {
                  "query": {
                    "match": {
                      "tags.tag": "landscape city"
                    }
                  },
                  "field_value_factor": {
                    "field": "tags.confidence",
                    "factor": 5,
                    "missing": 0
                  }
                }
              }
            }
          }]
        }
      },
      "functions": [
        {
          "field_value_factor": {
            "field": "boost_multiplier",
            "factor": 1,
            "missing": 0
          }
        },
        {
          "gauss": {
            "created_at": {
              "scale": "365d",
              "offset": "5d",
              "decay" : 0.5
            }
          }
        }
      ]
    }
  }
}

The problem was the documents had recent created_at value, so they were falling in offset, so no decay was calculated.

Ahmet Cetin
  • 3,683
  • 3
  • 25
  • 34