首页 > 解决方案 > 如何在 Elasticsearch 中使用多个字段匹配对存储桶中的文档进行排序?

问题描述

我正在使用 elasticsearch 7.9.0
我的索引有类似的文档

{
  "student": {
    "name": "Guru",
    "new_student": true,
    "total_marks": 100
  }
}
{
  "student": {
    "name": "Mayur",
    "new_student": false,
    "total_marks": 90
  }
}
{
  "student": {
    "name": "Darshan",
    "new_student": false,
    "total_marks": 0
  }
}
{
  "student": {
    "name": "Manu",
    "new_student": true,
    "total_marks": 0
  }
}

现在我的输出应该包含以下顺序中的结果。\

  1. 所有拥有"new_student":true和拥有的学生"total_marks" > 0
  2. 所有拥有"new_student":false和拥有的学生"total_marks" > 0
  3. 所有拥有"new_student":true和拥有的学生"total_marks" = 0
  4. 所有拥有"new_student":false和拥有的学生"total_marks" = 0

我们怎样才能做到这一点?
我尝试将引导添加到与上述字段单独匹配的布尔查询中。
然后我意识到我必须使用student.name. 如果我这样做,提升将没有任何效果。

然后我尝试了多搜索 API。我得到了预期的结果,但后来我意识到分页在多重搜索中很困难。

如何解决这个问题?
谢谢

标签: sortingelasticsearch

解决方案


可以在 should 子句中添加不同的function_score查询每个 function_score 将给一个组相同的分数。在排序中,分数和名称可用于对文档进行排序。由于每个组的分数相同,因此将按字母顺序排序

询问

{
  "query": {
    "bool": {
      "should": [
        {
          "function_score": {
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "student.new_student": {
                        "value": true
                      }
                    }
                  },
                  {
                    "range": {
                      "student.total_marks": {
                        "gt": 0
                      }
                    }
                  }
                ]
              }
            },
            "boost": "5"
          }
        },
        {
          "function_score": {
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "student.new_student": {
                        "value": false 
                      }
                    }
                  },
                  {
                    "range": {
                      "student.total_marks": {
                        "gt": 0
                      }
                    }
                  }
                ]
              }
            },
            "boost": "4"
          }
        },
        {
          "function_score": {
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "student.new_student": {
                        "value": true 
                      }
                    }
                  },
                  {
                    "range": {
                      "student.total_marks": {
                        "gte": 0,
                        "lte": 0
                      }
                    }
                  }
                ]
              }
            },
            "boost": "3"
          }
        },
        {
          "function_score": {
            "query": {
              "bool": {
                "must": [
                  {
                    "term": {
                      "student.new_student": {
                        "value": false 
                      }
                    }
                  },
                  {
                    "range": {
                      "student.total_marks": {
                        "gte": 0,
                        "lte": 0
                      }
                    }
                  }
                ]
              }
            },
            "boost": "2"
          }
        }
      ]
    }
  },
  "sort": [
    {
      "_score": {
        "order": "desc"
      }
    },
    {
      "student.name.keyword": {
        "order": "asc"
      }
    }
  ]
}

结果

  "hits" : [
      {
        "_index" : "index32",
        "_type" : "_doc",
        "_id" : "STtN5HsBssOzZCY8olFq",
        "_score" : 7.6949825,
        "_source" : {
          "student" : {
            "name" : "Abc",
            "new_student" : true,
            "total_marks" : 90
          }
        },
        "sort" : [
          7.6949825,
          "Abc"
        ]
      },
      {
        "_index" : "index32",
        "_type" : "_doc",
        "_id" : "RTsT5HsBssOzZCY8olGD",
        "_score" : 7.6949825,
        "_source" : {
          "student" : {
            "name" : "Guru",
            "new_student" : true,
            "total_marks" : 100
          }
        },
        "sort" : [
          7.6949825,
          "Guru"
        ]
      },
      {
        "_index" : "index32",
        "_type" : "_doc",
        "_id" : "RjsT5HsBssOzZCY8plFr",
        "_score" : 7.501875,
        "_source" : {
          "student" : {
            "name" : "Mayur",
            "new_student" : false,
            "total_marks" : 90
          }
        },
        "sort" : [
          7.501875,
          "Mayur"
        ]
      },
      {
        "_index" : "index32",
        "_type" : "_doc",
        "_id" : "SDsT5HsBssOzZCY8uFEe",
        "_score" : 4.6169896,
        "_source" : {
          "student" : {
            "name" : "Manu",
            "new_student" : true,
            "total_marks" : 0
          }
        },
        "sort" : [
          4.6169896,
          "Manu"
        ]
      },
      {
        "_index" : "index32",
        "_type" : "_doc",
        "_id" : "RzsT5HsBssOzZCY8rVFz",
        "_score" : 3.7509375,
        "_source" : {
          "student" : {
            "name" : "Darshan",
            "new_student" : false,
            "total_marks" : 0
          }
        },
        "sort" : [
          3.7509375,
          "Darshan"
        ]
      }
    ]

推荐阅读