Въпреки че изглежда сте се обърнали към тази структура поради проблем с актуализациите при използването на вложени масиви, вие всъщност само сте причинили друг проблем, като сте направили нещо друго, което всъщност не се поддържа, и това е, че няма "заместващ знак" концепция за търсене на неспецифицирани ключове с помощта на стандартните оператори за заявки, които са оптимални.
Единственият начин, по който наистина можете да търсите такива данни, е като използвате JavaScript код на сървъра, за да преминете през ключовете с помощта на $where
. Това очевидно не е наистина добра идея, тъй като изисква груба сила оценка, вместо да използва полезни неща като индекс, но може да се подходи по следния начин:
db.theses.find(function() {
var relations = this.relations;
return Object.keys(relations).some(function(rel) {
return relations[rel].type == "interpretation";
});
))
Докато това ще върне тези обекти от колекцията, които съдържат изискваната вложена стойност, то трябва да провери всеки обект в колекцията, за да направи оценката. Ето защо такава оценка наистина трябва да се използва само когато е съчетана с нещо, което може директно да използва индекс вместо като твърда стойност от обекта в колекцията.
И все пак по-доброто решение е да обмислите премоделиране на данните, за да се възползвате от индексите при търсене. Когато е необходимо да се актуализира информацията за „рейтинги“, тогава основно „изравнете“ структурата, която вместо това да разглежда всеки елемент "рейтинг" като единствения масив с данни:
{
"_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
}
]
}
Сега търсенето разбира се е доста просто:
db.theses.find({ "relationsRatings.type": "interpretation" })
И разбира се позиционният $
операторът вече може да се използва с по-плоската структура:
db.theses.update(
{ "relationsRatings.ratingId": 1 },
{ "$set": { "relationsRatings.$.ratingScore": 7 } }
)
Разбира се, това означава дублиране на „свързаните“ данни за всяка стойност на „оценки“, но това обикновено е цената на актуализирането по съответстваща позиция, тъй като това е всичко, което се поддържа само с едно ниво на влагане на масив.
Така че можете да принудите логиката да съвпадне с начина, по който сте я структурирали, но не е добра идея да го правите и ще доведе до проблеми с производителността. Ако обаче основната ви нужда тук е да актуализирате информацията за „рейтинги“, а не просто да добавите към вътрешния списък, тогава по-плоската структура ще бъде от по-голяма полза и, разбира се, ще бъде много по-бързо за търсене.