ElasticSearch 2桶级排序

时间:2015-08-31 07:04:51

标签: elasticsearch

数据库的映射是:

{
   "users": {
      "mappings": {
         "user": {
            "properties": {
              credentials": {
                  "type": "nested",
                  "properties": {
                     "achievement_id": {
                        "type": "string"
                     },
                     "percentage_completion": {
                        "type": "integer"
                     }
                  }
               },
               "current_location": {
                  "type": "geo_point"
               },
             "locations": {
               "type": "geo_point"
         }
            }
         }
      }
   }

现在在映射中,您可以看到有两个地理距离字段,一个是current_location,另一个是位置。现在我想基于credentials.percentage_completion对用户进行排序,这是一个嵌套字段。这工作正常,例如此查询, 示例查询:

GET /users/user/_search?size=23
{
  "sort": [
    {
      "credentials.percentage_completion": {
        "order": "desc",
        "missing": "_last"
      }
    },
 "_score"
  ],
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "geo_distance": {
          "distance": "100000000km",
          "user.locations": {
            "lat": 19.77,
            "lon": 73
          }
        }
      }
    }
  }
}

我想更改排序的排序顺序,所需的顺序首先显示所有位于user.current_location半径100KM的人,然后根据credentials.percentage_completion对其进行排序,然后通过credentials.percentage_completion再次对其他用户进行排序

我尝试将条件放入排序并使其成为多级,但这不起作用,因为只有嵌套可以有嵌入字段而嵌套字段只有子级。

我认为我可以使用_score进行排序,并为1000 km以下的人提供更多相关性,但地理距离是一个过滤器,我似乎没有找到任何方式来过滤相关性。

这里有什么我想念的,任何帮助都会很棒。

由于

1 个答案:

答案 0 :(得分:1)

最后解决了它,在这里发布,所以如果他们到这里,其他人也可以带头。解决这个问题的方法是给特定查询提供恒定的相关性分数,但是因为它是Geo distance所以无法在查询中使用它,然后我发现Constant Score query:它允许在查询中包装过滤器。

这是查询的外观:

GET /users/user/_search?size=23
{
  "sort": [
    "_score",
    {
      "credentials.udacity_percentage_completion": {
        "order": "desc",
        "missing": "_last"
      }
    }
  ],
  "explain": true,
  "query": {
    "filtered": {
      "query": {
        "bool": {
          "should": [
            {
              "constant_score": {
                "filter": {
                  "geo_distance": {
                    "distance": "100km",
                    "user.current_location": {
                      "lat": 19.77,
                      "lon": 73
                    }
                  }
                },
                "boost": 50
              }
            },
            {
              "constant_score": {
                "filter": {
                  "geo_distance": {
                    "distance": "1000000km",
                    "user.locations": {
                      "lat": 19.77,
                      "lon": 73
                    }
                  }
                },
                "boost": 1
              }
            }
          ]
        }
      },
      "filter": {
        "geo_distance": {
          "distance": "10000km",
          "user.locations": {
            "lat": 19.77,
            "lon": 73
          }
        }
      }
    }
  }
}