Mongo - подсчитайте размер разных именованных узлов (не их значения, а количество узлов)

В приведенном ниже 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"
        }
      ]
    }
  }

С произвольной глубиной именованных ключей это невозможно с фреймворком агрегации. Если у вас есть «заданная глубина» (например, всегда 2), то это возможно, но не совсем практично. Документ действительно должен быть структурирован по-другому, поэтому, если вы действительно объясните, как вы собираетесь использовать эту информацию, вы можете получить совет, как это сделать по-другому. В остальном это в значительной степени mapReduce только на текущей структуре.

Neil Lunn 04.11.2018 01:07

@NeilLunn о, спасибо, я совсем забыл о mapReduce. Думаю, это то, что мне нужно. Я подумал, что если бы я мог получить результат для 1, я мог бы каким-то образом объединить запросы, чтобы получить результаты для всех сразу.

StanM 04.11.2018 01:19

Основная проблема здесь - это «именованные ключи», которые просто не подходят для запросов к базе данных. Вот почему я предлагаю вам вместо этого «описать свой вариант использования» с помощью «реальных образцов данных» и того, как вы «действительно» хотите их использовать. Ваши «подсчеты» означают «агрегацию» той или иной формы (.distinct() - это метод «агрегации»), а не то, что на самом деле делают «запросы». Но если вы опишете свою цель, вы можете получить полезный совет по лучшей структуре. Этот текущий вызовет множество проблем.

Neil Lunn 04.11.2018 01:24

Я не уверен, что у меня есть реальный вариант использования - мои исходные данные взяты из API поиска изображений Google.

StanM 04.11.2018 01:44

Итак, такие ответы обычно имеют проблемы и требуют некоторой «очистки» (и некоторой «разумности») для типичного использования базы данных. Именованные ключи на узлах разумны для программного доступа из JavaScript (или чаще лениво конвертируются из XML :(), но довольно непрактичны для использования в базах данных. Лучшим вариантом является «хранить его так, как вы хотите его использовать», а не просто выгружать канал как было возвращено. Обратите внимание, что 90% этих «API» (и здесь выделяется Google) обычно создаются студентами-практикантами. Так что их, мягко говоря, может «не хватать».

Neil Lunn 04.11.2018 01:58
Использование JavaScript и MongoDB
Использование JavaScript и MongoDB
Сегодня я собираюсь вкратце рассказать о прототипах в JavaScript, а также представить и объяснить вам работу с базой данных MongoDB.
0
5
18
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Как указал НилЛанн, это можно сделать только с помощью 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;
|

Приносим извинения, если это не совсем компилируется - я изменил его на основе моих фактических данных, но это суть того, что я сделал, на случай, если это кому-то поможет. Если нужны подробности, добавлю.

Другие вопросы по теме