MongoDB
 sql >> база данни >  >> NoSQL >> MongoDB

$unwind обект в рамката за агрегиране

Не е възможно да направите типа изчисление, който описвате с рамката за агрегиране - и това е не защото няма $unwind метод за немасиви. Дори ако обектите person:value са документи в масив, $unwind няма да помогне.

Функцията "групиране по" (независимо дали в MongoDB или в която и да е релационна база данни) се извършва върху стойността на поле или колона. Групираме по стойност на полето и сума/средна стойност/и т.н. въз основа на стойността на друго поле.

Прост пример е вариант на това, което предлагате, поле за оценки е добавено към примерната колекция от статии, но не като карта от потребител към оценка, а като масив като този:

{ title : title of article", ...
  ratings: [
         { voter: "user1", score: 5 },
         { voter: "user2", score: 8 },
         { voter: "user3", score: 7 }
  ]
}

Сега можете да обобщите това с:

[ {$unwind: "$ratings"},
  {$group : {_id : "$ratings.voter", averageScore: {$avg:"$ratings.score"} } } 
]

Но този пример, структуриран както го описвате, би изглеждал така:

{ title : title of article", ...
  ratings: {
         user1: 5,
         user2: 8,
         user3: 7
  }
}

или дори това:

{ title : title of article", ...
  ratings: [
         { user1: 5 },
         { user2: 8 },
         { user3: 7 }
  ]
}

Дори ако можете да $unwind това, тук няма какво да се обобщава. Освен ако не знаете пълния списък на всички възможни ключове (потребители), не можете да направите много с това. [*]

Аналогична релационна DB схема на това, което имате, би била:

CREATE TABLE T (
   user1: integer,
   user2: integer,
   user3: integer
   ...
);

Не това ще бъде направено, вместо това ще направим това:

CREATE TABLE T (
   username: varchar(32),
   score: integer
);

и сега агрегираме с помощта на SQL:

select username, avg(score) from T group by username;

Има заявка за подобрение за MongoDB, която може да ви позволи да правите това в рамката за агрегиране в бъдеще - възможността да проектирате стойности към ключове и обратно. Междувременно винаги има карта/намаляване.

[*] Има сложен начин да направите това, ако знаете всички уникални ключове (можете да намерите всички уникални ключове с метод, подобен на този), но ако знаете всички ключове, можете също така просто да изпълните поредица от заявки на форма db.articles.find({"ratings.user1":{$exists:true}},{_id:0,"ratings.user1":1}) за всеки userX, който ще върне всичките им оценки и можете да ги сумирате и осредните достатъчно просто, вместо да правите много сложна проекция, която рамката за агрегиране ще изисква.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. SQL LPAD()

  2. Как да използвате моделиране на данни MongoDB за подобряване на операциите с пропускателна способност

  3. Преглед на оперативното отчитане на базата данни в ClusterControl

  4. Има ли начин за атомарно актуализиране на две колекции в MongoDB?

  5. Mongoose, намерете, върнете конкретни свойства