Även om du verkar ha närmat dig den här strukturen på grund av ett problem med uppdateringar av att använda kapslade arrayer, har du verkligen bara orsakat ett annat problem genom att göra något annat som inte riktigt stöds, och det är att det inte finns något "wildcard" koncept för att söka efter ospecificerade nycklar med de vanliga frågeoperatorerna som är optimala.
Det enda sättet du verkligen kan söka efter sådan data är att använda JavaScript-kod på servern för att gå igenom nycklarna med $where
. Detta är helt klart inte en riktigt bra idé eftersom det kräver brute force utvärdering snarare än att använda användbara saker som ett index, men det kan närma sig på följande sätt:
db.theses.find(function() {
var relations = this.relations;
return Object.keys(relations).some(function(rel) {
return relations[rel].type == "interpretation";
});
))
Även om detta kommer att returnera de objekt från samlingen som innehåller det nödvändiga kapslade värdet, måste det inspektera varje objekt i samlingen för att kunna göra utvärderingen. Det är därför en sådan utvärdering egentligen bara bör användas när den paras ihop med något som direkt kan använda ett index istället som ett hårt värde från objektet i samlingen.
Fortfarande den bättre lösningen är att överväga att omforma data för att dra fördel av index i sökningar. Där det är nödvändigt att uppdatera "betyg"-informationen, sedan i princip "platta ut" strukturen för att betrakta varje "rating"-element som den enda matrisdata istället:
{
"_id": "aeokejXMwGKvWzF5L",
"text": "test",
"relationsRatings": [
{
"relationId": "cF6iKAkDJg5eQGsgb",
"type": "interpretation",
"originId": "uFEjssN2RgcrgiTjh",
"ratingId": 1,
"ratingScore": 5
},
{
"relationId": "cF6iKAkDJg5eQGsgb",
"type": "interpretation",
"originId": "uFEjssN2RgcrgiTjh",
"ratingId": 2,
"ratingScore": 6
}
]
}
Nu är sökningen naturligtvis ganska enkel:
db.theses.find({ "relationsRatings.type": "interpretation" })
Och naturligtvis den positionella $
operatorn kan nu användas med den plattare strukturen:
db.theses.update(
{ "relationsRatings.ratingId": 1 },
{ "$set": { "relationsRatings.$.ratingScore": 7 } }
)
Naturligtvis innebär detta dubblering av "relaterade" data för varje "betyg"-värde, men detta är i allmänhet kostnaden för att uppdatera efter matchad position eftersom detta är allt som stöds med en enda nivå av array-kapsling.
Så du kan tvinga logiken att matcha med hur du har den strukturerad, men det är ingen bra idé att göra det och kommer att leda till prestandaproblem. Men om ditt huvudsakliga behov här är att uppdatera "betyg"-informationen istället för att bara lägga till den inre listan, kommer en plattare struktur att vara till större fördel och naturligtvis vara mycket snabbare att söka.