如何根据筛选数据对弹性搜索中的数据进行排序
How to sort data in elastic search based on the filter data
我对这个弹性搜索比较陌生。所以我以下面提到的方式将数据存储在弹性搜索中:
[{
"name": "user1",
"city": [{
"name": "city1",
"count": 18
},{
"name": "city2",
"count": 15
},{
"name": "city3",
"count": 10
},{
"name": "city4",
"count": 5
}]
},{
"name": "user2",
"city": [{
"name": "city2",
"count": 2
},{
"name": "city5",
"count": 5
},{
"name": "city6",
"count": 8
},{
"name": "city8",
"count": 15
}]
},{
"name": "user3",
"city": [{
"name": "city1",
"count": 2
},{
"name": "city5",
"count": 5
},{
"name": "city7",
"count": 28
},{
"name": "city2",
"count": 1
}]
}]
所以,我想做的是找出那些在城市列表中有 "city2" 的用户,然后 根据 "count" 的 "count" 对数据进行排序26=].
这是我尝试过的查询:
{
"sort": [{
"city.count": {
"order" : "desc"
}
}],
"query": {
"bool": {
"must": [
{"match": {"city.name": "city2"}}
]
}
}
}
所以我不知道排序部分该怎么做!
排序部分正在考虑基于过滤器的所有城市的所有 "count" 值,但我只想根据 "city2" 的 "count" 进行排序.
如有任何帮助,我们将不胜感激。提前致谢。
实现目标会有点复杂。
首先,您的查询表明您想获取其中包含 "city2" 的文档。由于数组 "city" 中至少有一个元素匹配,因此整个文档将被 returned.
问题是您只想 return city2 的计数,而不是所有城市的计数。这就是复杂部分的来源。
有很多路径可供选择:
更改您的索引设计。与其拥有一系列用户,不如为每个用户提供一个文档,其中包含他们的所有信息,包括他们访问过的城市。但是,"I only want 1 element from the array"的问题还是会存在,只是你一次只会打一个数组,而不是n个。
您可以使用 Painless 仅返回特定城市的计数,但这意味着需要编写大量脚本。不要相信这个名字。无痛是很痛的。
您可以带回所有元素并在您的代码中进行过滤。例如,如果您使用 Python Elasticsearch Client,您可以执行查询,return 所有对象,并且仅使用 Python.
来选择想要的元素
不考虑使用 Terms aggregation。它将带回所有城市的总计数,而无需与每个用户建立关系。而这不是你想要做的。
希望这对您有所帮助,很抱歉我们无法获得直接的解决方案:(
由于字段 city
是 object
而不是 nested object
,因此您想要实现的目标是不可能的。这样做的原因是,当您将一个字段定义为 object
时,elastics 将每个对象字段值展平为一个数组。所以,
"city": [
{
"name": "city1",
"count": 18
},
{
"name": "city2",
"count": 15
},
{
"name": "city3",
"count": 10
},
{
"name": "city4",
"count": 5
}
]
被索引为:
"city.name" : ["city1", "city2", "city3", "city4"]
"city.count": [18, 15, 10, 5]
如您所见,由于弹性索引对象的方式,每个城市与其计数之间的关系丢失了。
因此,只要您想保留关系,就应该将字段定义为 nested
类型。
{
"city": {
"type": "nested",
"properties": {
"name": {
"type": "text"
},
"count": {
"type": "long"
}
}
}
}
排序就可以用这个nested field.
{
"sort": [
{
"city.count": {
"order": "desc",
"mode": "avg",
"nested": {
"path": "city",
"filter": {
"match": {
"city.name": "city2"
}
}
}
}
}
],
"query": {
"bool": {
"must": [
{
"match": {
"city.name": "city2"
}
}
]
}
}
}
我对这个弹性搜索比较陌生。所以我以下面提到的方式将数据存储在弹性搜索中:
[{
"name": "user1",
"city": [{
"name": "city1",
"count": 18
},{
"name": "city2",
"count": 15
},{
"name": "city3",
"count": 10
},{
"name": "city4",
"count": 5
}]
},{
"name": "user2",
"city": [{
"name": "city2",
"count": 2
},{
"name": "city5",
"count": 5
},{
"name": "city6",
"count": 8
},{
"name": "city8",
"count": 15
}]
},{
"name": "user3",
"city": [{
"name": "city1",
"count": 2
},{
"name": "city5",
"count": 5
},{
"name": "city7",
"count": 28
},{
"name": "city2",
"count": 1
}]
}]
所以,我想做的是找出那些在城市列表中有 "city2" 的用户,然后 根据 "count" 的 "count" 对数据进行排序26=].
这是我尝试过的查询:
{
"sort": [{
"city.count": {
"order" : "desc"
}
}],
"query": {
"bool": {
"must": [
{"match": {"city.name": "city2"}}
]
}
}
}
所以我不知道排序部分该怎么做! 排序部分正在考虑基于过滤器的所有城市的所有 "count" 值,但我只想根据 "city2" 的 "count" 进行排序.
如有任何帮助,我们将不胜感激。提前致谢。
实现目标会有点复杂。
首先,您的查询表明您想获取其中包含 "city2" 的文档。由于数组 "city" 中至少有一个元素匹配,因此整个文档将被 returned.
问题是您只想 return city2 的计数,而不是所有城市的计数。这就是复杂部分的来源。
有很多路径可供选择:
更改您的索引设计。与其拥有一系列用户,不如为每个用户提供一个文档,其中包含他们的所有信息,包括他们访问过的城市。但是,"I only want 1 element from the array"的问题还是会存在,只是你一次只会打一个数组,而不是n个。
您可以使用 Painless 仅返回特定城市的计数,但这意味着需要编写大量脚本。不要相信这个名字。无痛是很痛的。
您可以带回所有元素并在您的代码中进行过滤。例如,如果您使用 Python Elasticsearch Client,您可以执行查询,return 所有对象,并且仅使用 Python.
来选择想要的元素
不考虑使用 Terms aggregation。它将带回所有城市的总计数,而无需与每个用户建立关系。而这不是你想要做的。
希望这对您有所帮助,很抱歉我们无法获得直接的解决方案:(
由于字段 city
是 object
而不是 nested object
,因此您想要实现的目标是不可能的。这样做的原因是,当您将一个字段定义为 object
时,elastics 将每个对象字段值展平为一个数组。所以,
"city": [
{
"name": "city1",
"count": 18
},
{
"name": "city2",
"count": 15
},
{
"name": "city3",
"count": 10
},
{
"name": "city4",
"count": 5
}
]
被索引为:
"city.name" : ["city1", "city2", "city3", "city4"]
"city.count": [18, 15, 10, 5]
如您所见,由于弹性索引对象的方式,每个城市与其计数之间的关系丢失了。
因此,只要您想保留关系,就应该将字段定义为 nested
类型。
{
"city": {
"type": "nested",
"properties": {
"name": {
"type": "text"
},
"count": {
"type": "long"
}
}
}
}
排序就可以用这个nested field.
{
"sort": [
{
"city.count": {
"order": "desc",
"mode": "avg",
"nested": {
"path": "city",
"filter": {
"match": {
"city.name": "city2"
}
}
}
}
}
],
"query": {
"bool": {
"must": [
{
"match": {
"city.name": "city2"
}
}
]
}
}
}