2

I have a few objects in the database: object 1, object 2, object 3, .., object n

Now I am doing filter like this

MyDocument.search().filter("match", is_active=True).sort('id').execute()

Output:

searchDocumentobject 1, searchDocumentobject 2,searchDocumentobject 3, ....

Now I need to searchDocumentobject 2 in last from the list.

Need the output like this:

searchDocumentobject 1,searchDocumentobject 3, .... , searchDocumentobject 2

Thank you

3
  • 1
    in case where there are 100 document and you only return 10 document, will the document 2 become the 10th or 100th document? Commented Apr 7, 2020 at 6:52
  • Thank you @TuyenLuong for your response. Actually I need all the documents so if I have 100 documents then I need document 2 is on the last element. Commented Apr 7, 2020 at 6:58
  • How about sorting the results on your needs after fetching from the ES? Commented Apr 7, 2020 at 7:18

2 Answers 2

2

In MyModel, add a new method, which returns 0 if you want to keep that document at last, else it'll return 1.

class MyModel(models.Model):

    # Add new method here
    def get_rank(self):
        if self.id == 2:  # your condition here
            return 0      # return 0, if you want to keep it at last
        return 1

Now, you can utilize this method in MyDocument. Add a new field in MyDocument, which we'll use for sorting.

class MyDocument(Document):
    # Add new field here
    rank = fields.IntegerField(attr='get_rank')

Now, you can query like this,

MyDocument.search().filter("match", is_active=True).sort('-rank', 'id').execute()
Sign up to request clarification or add additional context in comments.

Comments

2

You can achieve this behavior in your search request using function score, the idea is that each other documents you'll have score of 1 (default) and with document 2 you give it lower score then sort by "_score", "id". Here is the DSL, try construct the query from your python API:

{
  "_source": ["id"], 
  "query": {
    "function_score": {
      "query": {
        "bool": {
           //add your query here
           "must": [
             {
               "terms": {
                 "id": [1, 2, 3, 70]
               }
             }
           ]
         }
      },
      "functions": [
        {
          "filter": {
            "term": {
              "id": 2
            }
          },
          "weight": 0.5
        }
      ]
    }
  }, 

  "sort": [
    "_score",
    {
      "id": {
        "order": "asc"
      }
    }
  ]
}

Also as Yifeng stated in comment section, you can re-sort the results after you query from ES.

3 Comments

weight influences all queries, not only this one. So, if you are searching regularly on fields, the document with ID 2 will start off with a lower ranking. This might be the desired effect, though.
Thank you @Risadinha I could not understand you, Can you explain with example? How can I set a lower ranking?
In a regular search, you would e.g. search for "red shoes" in a field. Supposed the document with id 2 contains exactyl "red shoes" as phrase while document with id 1 has the text "blue shoes ... ... red something". Id 1 should get a lower score than id 2, however, a weight of 0.5 will lower the score of id 2 - it might then end up lower than other documents even if it is more relevant for this given search input.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.