具有特定输出的Elasticsearch DSL查询

2024-06-17 06:10:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我在数据库中有几个对象: 对象1、对象2、对象3、…、对象n

现在我正在做这样的过滤

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

输出:

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

现在我需要从列表中最后搜索DocumentObject 2

需要这样的输出:

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

多谢各位


Tags: 对象id数据库true列表executesearchis
2条回答

您可以使用函数得分在搜索请求中实现此行为,其思想是,每个其他文档的得分为1(默认值),而文档2的得分较低,然后按“_得分”、“id”排序。这是DSL,请尝试从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"
      }
    }
  ]
}

同样,正如Yifeng在评论部分所述,您可以在从ES查询后对结果重新排序

在MyModel中,添加一个新方法,如果您希望最后保留该文档,该方法将返回0,否则将返回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

现在,您可以在MyDocument中使用此方法。在MyDocument中添加一个新字段,用于排序

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

现在,您可以这样查询

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

相关问题 更多 >