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

Групиране на документи по двойки с помощта на агрегиране на mongo

Това е нещо, което просто не може да се направи с рамката за агрегиране и единственият текущ метод на MongoDB, наличен за този тип операции, е mapReduce.

Причината е, че рамката за агрегиране няма начин да се позовава на друг документ в процес на подготовка освен настоящия. Това всъщност се отнася и за етапите на "групиране" на тръбопровода, тъй като въпреки че нещата са групирани по "ключ", не можете наистина да се справите с отделни документи по начина, по който искате.

MapReduce от друга страна има една налична функция, която ви позволява да правите това, което искате тук, и дори не е „пряко“ свързана с агрегацията. Всъщност това е способността да има "променливи с глобален обхват" на всички етапи. И наличието на „променлива“, която да „съхранява последния документ“ е всичко, от което се нуждаете, за да постигнете резултата.

Така че това е доста прост код и всъщност не е необходимо „намаляване“:

db.collection.mapReduce(
    function () {
      if (lastVal != null)
        emit( this._id, this.val - lastVal );
      lastVal = this.val;
    },
    function() {}, // mapper is not called
    {
        "scope": { "lastVal": null },
        "out": { "inline": 1 }
    }
)

Което ви дава резултат, подобен на този:

{
    "results" : [
            {
                    "_id" : ObjectId("54a425a99b8bcd6f73e2d662"),
                    "value" : 2
            },
            {
                    "_id" : ObjectId("54a425a99b8bcd6f73e2d663"),
                    "value" : 3
            },
            {
                    "_id" : ObjectId("54a425a99b8bcd6f73e2d664"),
                    "value" : 4
            }
    ],
    "timeMillis" : 3,
    "counts" : {
            "input" : 4,
            "emit" : 3,
            "reduce" : 0,
            "output" : 3
    },
    "ok" : 1
}

Това наистина е просто избиране на „нещо уникално“ като излъчен _id стойност, а не нещо конкретно, защото всичко, което наистина прави, е разликата между стойностите на различни документи.

Глобалните променливи обикновено са решението за тези типове "сдвояване" на агрегации или създаване на "текущи суми". В момента рамката за агрегиране няма достъп до глобални променливи, въпреки че може да е хубаво да има това. Рамката mapReduce ги има, така че вероятно е справедливо да се каже, че те трябва да бъдат достъпни и за рамката за агрегиране.

В момента обаче не са, така че се придържайте към mapReduce.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Проверка на здравето на Mongodb стъпка по стъпка

  2. командата mongorestore заменя съществуващите записи?

  3. MongoDB .NET не генерира _id при upsert

  4. Как да получа датата на създаване на колекция MongoDB с помощта на драйвер на MongoDB C#?

  5. Как да установя peering между MongoDB Atlas и Google App Engine Standard Environment Node App