我有以下内容:
PUT players
{
"mappings": {
"player": {
"properties": {
"name": {
"type": "string"
}
}
}
}
}
PUT players/player/1
{
"name": "Dave"
}
PUT players/player/2
{
"name": "Dan"
}
PUT players/player/3
{
"name": "Macey"
}
PUT score
{
"mappings": {
"score": {
"properties": {
"player": {
"type": "string"
},
"score": {
"type": "integer"
}
}
}
}
}
PUT score/score/1
{
"player": "3",
"action": "10"
}
PUT score/score/2
{
"player": "2",
"action": "5"
}
PUT score/score/3
{
"player": "3",
"action": "10"
}
PUT score/score/4
{
"player": "2",
"action": "7"
}
PUT score/score/5
{
"player": "1",
"action": "1"
}
PUT score/score/6
{
"player": "1",
"action": "2"
}
PUT score/score/7
{
"player": "1",
"action": "2"
}
PUT score/score/8
{
"player": "1",
"action": "1"
}
PUT score/score/9
{
"player": "1",
"action": "8"
}
我不知道我在做什么。我需要按总分(按降序排列)对球员进行排序。所以,如果我查询“Da”,我想得到:
1. Dave - 14
2. Dan - 12
到目前为止,我有:
GET /players/_search
{
"query": {
"bool": {
"must": {
"term": {
"name": "Da"
}
}
}
}
}
我知道这不对。我主要来自一个SQL世界,我很难搞清楚如何加入表并按字段计数。感谢您的任何提示!
答案 0 :(得分:0)
为了解释handling relationships上的文档,Elasticsearch文档是孤立的,没有办法在文档之间建立简单的关系。
要解决这个困境,最简单的解决方案之一就是将您的数据非正规化 1 ,在您的{{1}中存储您的玩家数据(可能会修剪到您的搜索工作所需的数据)文档并处理该索引。
例如,您可以将score
索引定义为
score
你会用
填写它{
"mappings": {
"score": {
"properties": {
"player": {
"properties": {
"id": {
"type": "integer"
},
"nom": {
"type": "string",
"index": "not_analyzed"
}
}
},
"score": {
"type": "integer"
}
}
}
}
}
请注意,我已将PUT score/score/1
{
"player": {
"id": 3,
"name": "Macey"
},
"score": "10"
}
PUT score/score/2
{
"player": {
"id": 2,
"name": "Dan"
},
"score": "5"
}
PUT score/score/3
{
"player": {
"id": 3,
"name": "Macey"
},
"score": "10"
}
键替换为action
。
假设您需要对名称进行前缀查询(score
为player.name
的原因),您的查询将如下所示
not_analyzed
最后,要获得每位玩家的最高分,您可以使用聚合:
"query": {
"bool": {
"must": {
"prefix": {
"player.name": "da"
}
}
}
}
顶级agg按玩家ID定义存储桶,按{
"query": {
"bool": {
"must": {
"prefix": {
"player.name": "da"
}
}
}
},
"aggs" : {
"players" : {
"terms" : {
"field" : "player.id" ,
"order" : { "maxvalue" : "desc" }
},
"aggs" : {
"maxvalue": { "max" : { "field" : "score" } },
"maxscore": {
"top_hits": {
"sort": [
{
"score": {
"order": "desc"
}
}
],
"size" : 1
}
}
}
}
}
}
子聚合对其进行排序,然后通过maxvalue
聚合提取最高得分。
结果在Elasticsearch中有点冗长,你会得到类似的东西(减去查询结果)
top_hits
1 我知道它在SQL世界中是个坏词,但你已经习惯了。
答案 1 :(得分:0)
您可以利用子父关系来支持您的数据。您可以将玩家个人资料创建为父文档,将他们的分数创建为子文档。以下是parent-child relationship document的链接。
我为你创建了支持父子关系的映射
PUT testindex12
{
"settings": {
"analysis": {}
},
"mappings": {
"player": {
"properties": {
"players": {
"type": "string"
}
}
},
"score": {
"_parent": {
"type": "player"
},
"_routing": {
"required": true
},
"properties": {
"player": {
"type": "string"
},
"score": {
"type": "integer"
}
}
}
}
}
有关映射父子检查this link的更多信息。
索引父文件和子文件。
POST testindex12/player/1
{
"player" : "sachin"
}
POST testindex12/player/2
{
"player" : "rahul"
}
POST testindex12/player/3
{
"player" : "virat"
}
POST testindex12/score?parent=3
{
"score": 789
}
有关索引父子文档的更多信息,请参阅this link。
以下是我只是在名称上进行过滤的查询,在这里我想指向你,因为你试图对玩家的名字进行部分搜索,所以你可以在名字上使用前缀搜索。以下是prefix query的文档。为了根据分数对文档进行评分,我使用了功能评分。您可以找到有关他们的更多信息here。
POST testindex12/_search
{
"query": {
"bool": {
"must": [
{ "prefix": {
"player": {
"value": "sa"
}
}
},{
"has_child": {
"type": "score",
"score_mode": "sum",
"query": {
"function_score": {
"query": {
"match_all": {}
},
"score_mode": "sum",
"boost_mode": "sum",
"script_score": {
"script": "_score + doc['score'].value"
}
}
}
}
}]
}
}
}
我将不再使用nikoshr做的其他解决方案,因为聚合总共有不同的用途,当然也不能用于评分文档。
希望这会有所帮助。 感谢