在Elasticsearch中查询排序的嵌套文档

时间:2019-10-11 06:28:47

标签: elasticsearch

如果我要查询的查询非常简单明了,我是Elasticsearch和歉意的新手。

我正在使用以下学生及其学习细节的映射图,

PUT students
{
  "mappings" : {
      "properties" : {
        "StudentName" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "Education" : {
          "type" : "nested",
          "properties" : {
            "degreeName" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "schoolName" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "endDate" : {
              "type" : "date"
            },
            "startDate" : {
              "type" : "date"
            }
          }
        }
      }
  }
}

我的数据集中有近15000名学生。 文档示例:

PUT students/_doc/2
{
  "StudentName":"Student 2",
  "Education": [
    {
      "degreeName": "MS",
      "schoolName": "School Y",
      "startDate": "2016-05-01",
      "endDate":"2014-01-01"
    },
    {
      "degreeName": "PhD",
      "schoolName": "School X",
      "startDate": "2019-01-01",
      "endDate":"2017-05-01"
    },
    {
      "degreeName": "BE",
      "schoolName": "School Z",
      "startDate": "2013-05-01",
      "endDate":"2009-01-01"
    }]
}

PUT students/_doc/3
{
  "StudentName":"Student 3",
  "Education": [
    {
      "degreeName": "BE",
      "schoolName": "School P",
      "startDate": "2003-01-01",
      "endDate":"1999-05-01"
    }]
}

我的问题是,我正在尝试做一个简单的查询来显示以“ BE”为学位的学生。但是我希望拥有工程学学士学位的学生的排名要比拥有硕士和博士学位的学生更高。

从我的示例中,如果我查询“ BE”,则学生3的排名应高于学生2。我应该能够基于“ endDate”属性以降序对嵌套文档进行排序,然后在“ degreeName”匹配时进行排序嵌套字段的第一个元素中的“ BE”。

有人可以对此有所启发吗?我经历了嵌套查询,嵌套过滤器。我确实知道如何使用“内部匹配”对嵌套字段中的元素进行排序。但是我想知道是否有任何方法可以进行排序,然后进行查询以提供额外的帮助。

谢谢。

1 个答案:

答案 0 :(得分:0)

最简单的解决方案是在should子句中包含must子句,在should子句中,您仅提及让学生 with BE but without MS or PhD

这一切都在您的Boolean Query

请注意,must在逻辑上类似于AND,而should将是OR

完成后,您只需使用_scoreSort中的逻辑(如链接中所述)添加到 first 排序中,然后基于 Education.endDate 字段。

下面是解决方案:

POST students/_search
{
  "query": {
    "bool": {
      "must": [
        {
          "match" :{
            "StudentName": "student"
          }
        }
      ], 
      "should": [
        {
          "bool": {
            "must": [
              {
                "nested": {
                  "path": "Education",
                  "query": {
                    "terms": {
                      "Education.degreeName.keyword": [
                        "BE"
                      ]
                    }
                  }
                }
              }
            ],
            "must_not": [
              {
                "nested": {
                  "path": "Education",
                  "query": {
                    "terms": {
                      "Education.degreeName.keyword": [
                        "MS",
                        "PhD"
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      ]
    }
  },
  "sort": [
    { "_score" : { "order": "desc"}},
    {
      "Education.endDate": {
        "order": "desc"
      }
    }
  ]
}

让我知道这是否有帮助!

相关问题