Всичко в това е доста ужасно, не можете да индексирате нещо като стойностите на "name" и вашият "път" към всеки атрибут ще варира навсякъде. Така че това е наистина лошо за заявките.
Забелязвам, че споменавате „вложени“ структури и все пак бихте могли да се приспособите към това с подобно предложение и някои допълнителни етикети, но искам да вземете предвид този пример от типа „телефонен указател“:
{
"phones": [
{
"type": "Home",
"name" : "Jeff",
"phone" : "123-123-1234"
},
{
"type": "Work",
"name" : "Jeff",
"phone" : "123-123-1234"
},
]
}
Тъй като това всъщност са поддокументи в рамките на масив, полета като „име“ винаги споделят един и същ път, така че не само можете да ги индексирате (което ще бъде добре за производителността), но и заявката е много проста:
db.collection({ "phones.name": "Jeff" })
Това прави точно това, от което се нуждаете, като намерите "Джеф" във всеки запис "име". Ако имате нужда от йерархия, добавете няколко полета в тези поддокументи, за да посочите връзката родител/дете, която можете да използвате при последваща обработка. Или дори като материализиран път, който може да помогне на вашите запитвания.
Това наистина е по-добрият подход.
Ако наистина трябва да запазите този вид структура, тогава поне направете нещо подобно с JavaScript, който ще се спаси при първото съвпадение в дълбочина:
db.collection.find(
function () {
var found = false;
var finder = function( obj, field, value ) {
if ( obj.hasOwnProperty(field) && obj[field] == value )
found = true;
if (found) return true;
for( var n in obj ) {
if ( Object.prototype.toString.call(obj[n]) === "[object Object]" ) {
finder( obj[n], field, value );
if (found) return true;
}
}
};
finder( this, "name", "Jeff" );
return found;
}
)
Форматът там е съкратена нотация за $where
оператор, което е доста лоша новина за производителността, но вашата структура не предлага много друг избор. Във всеки случай функцията трябва да рекурсира във всеки вложен документ, докато не бъде намерено „полето“ със „стойността“.
За нещо от производствен мащаб наистина помислете за промяна на структурата към нещо, което може да бъде индексирано и достъпно бързо. Първият пример трябва да ви даде отправна точка. Разчитането на произволен JavaScript за заявки, както ви ограничава сегашната ви структура, е лоша новина.