esta é a aparência da parte relevante de um documento:
{
"map": {
"cities": [
{
"name": "City1",
"x": 15,
"y": 5,
"owner": 1,
"defense": 6,
"income": 35
},
{
"name": "City2",
"x": 12,
"y": 14,
"owner": 0,
"defense": 4,
"income": 16
},
{
"name": "City3",
"x": 6,
"y": 19,
"owner": 2,
"defense": 3,
"income": 12
}
]
},
"players": [
{
"userid": "64d3ebfb42fb5b118b928f5c",
"faction": 1
},
{
"userid": "636f89f0d4666b666237cec8",
"faction": 2
}
]
}
Agora, como escrever uma consulta que produza isso, se eu for o jogador 1 (userid: "64d3ebfb42fb5b118b928f5c"):
{
"map": {
"cities": [
{
"name": "City1",
"x": 15,
"y": 5,
"owner": 1,
"defense": 6,
"income": 35
},
{
"name": "City2",
"x": 12,
"y": 14,
"owner": 0
},
{
"name": "City3",
"x": 6,
"y": 19,
"owner": 2
}
]
}
}
No caso do jogador 2 ele retornará (userid: "636f89f0d4666b666237cec8"):
{
"map": {
"cities": [
{
"name": "City1",
"x": 15,
"y": 5,
"owner": 1
},
{
"name": "City2",
"x": 12,
"y": 14,
"owner": 0
},
{
"name": "City3",
"x": 6,
"y": 19,
"owner": 2,
"defense": 3,
"income": 12
}
]
}
}
- a consulta deve levar apenas o ID do usuário como entrada
- somente onde "players.faction" corresponde a "map.cities.owner", os valores reais de "defesa" e "renda" são mostrados
- um jogador não verá os valores das cidades que não possui
- uma alternativa poderia ser que os valores padrão sejam, por exemplo, 0 se o jogador não for o dono da cidade
Eu sei que posso apenas consultá-lo e removê-lo programaticamente, mas me pergunto se isso pode ser feito de alguma forma melhor.
Eu tentei assim, mas obviamente não funciona porque "$map.cities.owner"/"$map.cities.defense" na verdade é/retorna um array.
{
_id: 0,
"map.cities.name": 1,
"map.cities.x": 1,
"map.cities.y": 1,
"map.cities.owner": 1,
"map.cities.defense": {
$cond: {
if: {
$eq: ["$map.cities.owner", 1],
},
then: "$map.cities.defense",
else: "$$REMOVE",
},
},
}
Tentei usar $filter
, mas rapidamente ficou muito complicado e nunca obtive o resultado que procurava.
Tentei usar $unwind
, map.cities
mas tive dificuldade para colocá-lo em um único documento novamente.
Uma opção é usar o do usuário
faction
comovar
(de acordo com seufaction
) e depois$map
omap
para filtrá-lo:Veja como funciona no playground do mongodb