# Function\_score with order

**URL:** <https://discuss.elastic.co/t/function-score-with-order/164049>\
**Category:** Elasticsearch\
**Created:** [January 13, 2019, 6:02pm UTC](https://discuss.elastic.co/t/function-score-with-order/164049 "2019-01-13T18:02:35Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![qballer](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/qballer/32/39513_2.png) [@qballer](https://discuss.elastic.co/u/qballer)\
**Post date:** [January 13, 2019, 6:02pm UTC](https://discuss.elastic.co/t/function-score-with-order/164049/1 "2019-01-13T18:02:35Z")

</div>

I have documents which I calculate a function\_score with the search query below. The scoring seems to work well yet some documents get the same score. This causes results to repeat and to some never comer back. In essence I am sorting by scoring. I wonder if I can apply some secondary sorting to the results so order (a.k.a scoring) will be unique. For example each document has a unique string and I would like to order groups of documents with the same score by it.

```auto
{
  "from": "some_number",
  "size": "some_number",
  "query": {
    "function_score": {
      "query": {
        "bool": {
          "should": [
            "some terms ..."
          ],
          "minimum_should_match": 1,
          "must": [
            "some must filters"
          ]
        }
      },
      "functions": [
        {
          "gauss": {
            "createdAt": {
              "scale": "30d",
              "decay": 0.8
            }
          },
          "weight": 0.3
        },
        {
          "script_score": {
            "script": {
              "source": "return _score + some calulation"
            }
          },
          "weight": 0.6
        }
      ],
      "boost_mode": "sum"
    }
  }
}

```

I've tried several things like applying a sort and field\_value\_factor, but that doesn't seem to work. I will appreciate any other tips.

---

<div class="post-metadata">

**Author:** ![abdon](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/abdon/32/9195_2.png) [@abdon](https://discuss.elastic.co/u/abdon)\
**Post date:** [January 14, 2019, 3:26am UTC](https://discuss.elastic.co/t/function-score-with-order/164049/2 "2019-01-14T03:26:02Z")

</div>

When you say applying a sort did not work, can you explain why not? It is a common pattern to sort on a document's `_id` as the secondary sort order, as a tie breaker, if you wish to get a consistent ordering.

Something like this should work:

```auto
GET _search
{
  "query": {
    "function_score": {
      "query": {
        YOUR QUERY
      },
      "functions": [
        YOUR FUNCTIONS
      ]
    }
  },
  "sort": [
    {
      "_score": {
        "order": "desc"
      }
    },
    {
      "_id": {
        "order": "desc"
      }
    }
  ]
}

```

---

<div class="post-metadata">

**Author:** ![qballer](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/qballer/32/39513_2.png) [@qballer](https://discuss.elastic.co/u/qballer)\
**Post date:** [January 14, 2019, 9:54am UTC](https://discuss.elastic.co/t/function-score-with-order/164049/3 "2019-01-14T09:54:45Z")

</div>

> [@qballer](#):
>
> { "gauss": { "createdAt": { "scale": "30d", "decay": 0.8 } }, "weight": 0.3 },

I've tried this type of sorting before but reading your recommendation i've tried again. It seems that this function is the culprit, when I comment out this scoring method there are no duplicates in the results. The values are all in the same time (or around) so I understand why there are duplicates but I don't understand why the secondary sort doesn't take of that.

---

<div class="post-metadata">

**Author:** ![abdon](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/abdon/32/9195_2.png) [@abdon](https://discuss.elastic.co/u/abdon)\
**Post date:** [January 14, 2019, 4:32pm UTC](https://discuss.elastic.co/t/function-score-with-order/164049/4 "2019-01-14T16:32:27Z")

</div>

I'm guessing that what's happening is this: all documents have a slightly different value for `createdAt`. As a result they get a different score. Even if two documents differ by just a few miliseconds, the score is going to be slightly different and as a result, the secondary sort order is not going to play a factor.

Would it be possible to reindex your documents with less precise values for `createdAt`? For example, if you round down `createdAt` to the closed hour, then all documents that were created at about the same time will get the same score. Then you will be able to get to your desired deterministic sort order by using the `_id` as the secondary sort criterion.

---

<div class="post-metadata">

**Author:** ![qballer](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/qballer/32/39513_2.png) [@qballer](https://discuss.elastic.co/u/qballer)\
**Post date:** [January 14, 2019, 4:34pm UTC](https://discuss.elastic.co/t/function-score-with-order/164049/5 "2019-01-14T16:34:07Z")

</div>

Perhaps I don't understand something doesn't scale do that somehow?

---

<div class="post-metadata">

**Author:** ![abdon](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/abdon/32/9195_2.png) [@abdon](https://discuss.elastic.co/u/abdon)\
**Post date:** [January 14, 2019, 5:15pm UTC](https://discuss.elastic.co/t/function-score-with-order/164049/6 "2019-01-14T17:15:36Z")

</div>

No, `scale` determines how fast the score goes to zero the further you get from the current datetime. See this diagram in our [documentation](https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html#function-decay):

[![](https://www.elastic.co/guide/en/elasticsearch/reference/current/images/decay_2d.png) ](https://www.elastic.co/guide/en/elasticsearch/reference/current/images/decay_2d.png)

---

<div class="post-metadata">

**Author:** ![qballer](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/qballer/32/39513_2.png) [@qballer](https://discuss.elastic.co/u/qballer)\
**Post date:** [January 14, 2019, 8:49pm UTC](https://discuss.elastic.co/t/function-score-with-order/164049/7 "2019-01-14T20:49:24Z")

</div>

Rounding down to an hour can work but will eventually change order. Why not compare to epoch time some how (asc ordering?). Seems to make more sense stability wise.

---

<div class="post-metadata">

**Author:** ![abdon](https://sea2.discourse-cdn.com/elastic/user_avatar/discuss.elastic.co/abdon/32/9195_2.png) [@abdon](https://discuss.elastic.co/u/abdon)\
**Post date:** [January 16, 2019, 9:14pm UTC](https://discuss.elastic.co/t/function-score-with-order/164049/8 "2019-01-16T21:14:48Z")

</div>

Maybe I'm misunderstanding your issue. Internally, Elasticsearch stores dates as epoch milliseconds. My assumption was that what you are seeing is caused by documents not having the exact same value for createdAt. As a result, those documents all get a different score.

---

<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:** [February 13, 2019, 9:14pm UTC](https://discuss.elastic.co/t/function-score-with-order/164049/9 "2019-02-13T21:14:51Z")

</div>

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