В приведенном ниже json я хотел бы узнать количество всех уникальных / различных записей в нескольких разных узлах.
Я думаю, что должно быть решение для фреймворка без агрегирования, но я не могу найти ни агрегирования, ни неагрегации.
Для каждого узла я могу подсчитать его, используя:
db.collection.distinct('nodaA.title').length
И замените "" соответствующим полем для других узлов. Но я хочу получить количество «NodeB.subNoda1.author», «NodeB.subNode2.song» и «NodeB.subNode3.picture» всего с помощью одного запроса.
Я хочу получить результат типа
титул: 1
автор: 2
песня: 3
фото: 1
"nodaA": [
{
"title": "light",
"id" : 1
}
],
"NodeB": {
"subBnode1": [
{
"author": "Gazundheit"
},
{
"author": "Max Weasley"
}
],
"subBnode2": [
{
"song" : "what is love"
},
{
"song" : "gangster's paradise"
},
{
"song" : "wind is gone"
}
],
"subBnode3": [
{
"picture" : "inappropriate"
}
]
}
}
@NeilLunn о, спасибо, я совсем забыл о mapReduce. Думаю, это то, что мне нужно. Я подумал, что если бы я мог получить результат для 1, я мог бы каким-то образом объединить запросы, чтобы получить результаты для всех сразу.
Основная проблема здесь - это «именованные ключи», которые просто не подходят для запросов к базе данных. Вот почему я предлагаю вам вместо этого «описать свой вариант использования» с помощью «реальных образцов данных» и того, как вы «действительно» хотите их использовать. Ваши «подсчеты» означают «агрегацию» той или иной формы (.distinct() - это метод «агрегации»), а не то, что на самом деле делают «запросы». Но если вы опишете свою цель, вы можете получить полезный совет по лучшей структуре. Этот текущий вызовет множество проблем.
Я не уверен, что у меня есть реальный вариант использования - мои исходные данные взяты из API поиска изображений Google.
Итак, такие ответы обычно имеют проблемы и требуют некоторой «очистки» (и некоторой «разумности») для типичного использования базы данных. Именованные ключи на узлах разумны для программного доступа из JavaScript (или чаще лениво конвертируются из XML :(), но довольно непрактичны для использования в базах данных. Лучшим вариантом является «хранить его так, как вы хотите его использовать», а не просто выгружать канал как было возвращено. Обратите внимание, что 90% этих «API» (и здесь выделяется Google) обычно создаются студентами-практикантами. Так что их, мягко говоря, может «не хватать».

Как указал НилЛанн, это можно сделать только с помощью MapReduce, вот что у меня получилось:
карта:
function () {
emit("titles", this.title);
for (var key in this.nodeB) {
emit(key, this.nodeB[key]);
}
}
уменьшать:
function (key, values) {
var reducedValue = array.length;
return reducedValue;
|
Приносим извинения, если это не совсем компилируется - я изменил его на основе моих фактических данных, но это суть того, что я сделал, на случай, если это кому-то поможет. Если нужны подробности, добавлю.
С произвольной глубиной именованных ключей это невозможно с фреймворком агрегации. Если у вас есть «заданная глубина» (например, всегда 2), то это возможно, но не совсем практично. Документ действительно должен быть структурирован по-другому, поэтому, если вы действительно объясните, как вы собираетесь использовать эту информацию, вы можете получить совет, как это сделать по-другому. В остальном это в значительной степени
mapReduceтолько на текущей структуре.