4

I'm trying to _update_by_query in order to rank items in a sorted search. Is it possible to get the current "index" of the document in the script?

eg.

create index:

PUT test
{
    "mappings" : {
        "person" : {
            "properties" : {
                "score" : { "type" : "integer" },
                "rank" : { "type" : "integer" }
            }
        }
    }
}  

add documents:

POST /test/person/1
{
  "score": 100,
  "rank": 0
}
POST /test/person/2
{
  "score": 200,
  "rank": 0
}

run _update_by_query:

POST /test/_update_by_query
{
  "script": {
    "source": "ctx._source.rank=3", // how to get document "index" in sort here?
    "lang": "painless"
  },
  "sort": { "score": "desc" }
}

results when sorting by ascending rank should be

score: 200, rank: 1
score: 100, rank: 2
buddemat
  • 4,552
  • 14
  • 29
  • 49

1 Answers1

0

Looks like you are trying to update a single document. For this, the _update API would be a more appropriate choice. For example:

POST test/_update/1
{
    "script" : {
        "source": "ctx._source.rank=params.rank",
        "lang": "painless",
        "params" : {
            "rank" : 4
        }
    }
}

In the above case, you can see the document ID is provided to the API which updates only that document.

In contrast, the _update_by_query API performs an update on every document in the index. So, if you need to update more than one document based on a script, this would be your go to.

Hope it helps...

Muhammad Ali
  • 712
  • 7
  • 14
  • Thanks for the reply. I'm not trying to update single document, I'm trying to update many documents. The question is when updating by script and sorting by the score, how can I store the index of the sort for the script so that I can increment the rank? I believe this is not possible though. eg: I have 10 persons that have different scores and I want to update the rank so that highest score has rank 1 and lowest score has rank 10. I can do this by first retrieving all the 10 documents from the index, iterate through and update ranks and then update all the documents in the index. – user2416702 Sep 17 '19 at 08:30
  • Now I understand what you mean. You're right, at sorting time, this information is not known at document level, because of the underlying data-structure. If it makes sense, I'd suggest you go for a critieria that defines the ranks. For example, if score is greather than something -> rank 1 etc. This will enable you to scale for larger number of players. For the leaderboards, you can compute the 'position' of the players because after the query, the datastructure is a list, which has indexes. – Muhammad Ali Sep 17 '19 at 09:45
  • yep, thanx for looking into this! – user2416702 Sep 30 '19 at 12:17