MongoDB
 sql >> Baza danych >  >> NoSQL >> MongoDB

Unikalne wyniki Rails &Mongoid

Nie można po prostu zwrócić dokumentu (lub podzbioru) przy użyciu znaku odrębnego. Zgodnie z dokumentacją zwraca tylko odrębną tablicę wartości na podstawie podanego klucza. Ale możesz to osiągnąć, używając map-reduce

var _map = function () {
    emit(this.hash.call_id, {doc:this});
}

var _reduce = function (key, values) {
    var ret = {doc:[]};
    var doc = {};
    values.forEach(function (value) {
    if (!doc[value.doc.hash.call_id]) {
           ret.doc.push(value.doc);
           doc[value.doc.hash.call_id] = true; //make the doc seen, so it will be picked only once
       }
    });
    return ret;
}

Powyższy kod nie wymaga wyjaśnień, w funkcji mapy grupuję go klawiszem hash.call_id i zwrócenie całego dokumentu, aby można go było przetworzyć przez zmniejszenie funkcji.

W funkcji zmniejszania po prostu przejdź przez zgrupowany zestaw wyników i wybierz tylko jeden element z zgrupowanego zestawu (spośród wielu zduplikowanych wartości klucza - odrębna symulacja).

Na koniec utwórz dane testowe

> db.disTest.insert({hash:{call_id:"1234"},something:"AAA"})
> db.disTest.insert({hash:{call_id:"1234"},something:"BBB"})
> db.disTest.insert({hash:{call_id:"1234"},something:"CCC"})
> db.disTest.insert({hash:{call_id:"5555"},something:"DDD"})
> db.disTest.insert({hash:{call_id:"5555"},something:"EEE"})
> db.disTest.find()
{ "_id" : ObjectId("4f30a27c4d203c27d8f4c584"), "hash" : { "call_id" : "1234" }, "something" : "AAA" }
{ "_id" : ObjectId("4f30a2844d203c27d8f4c585"), "hash" : { "call_id" : "1234" }, "something" : "BBB" }
{ "_id" : ObjectId("4f30a2894d203c27d8f4c586"), "hash" : { "call_id" : "1234" }, "something" : "CCC" }
{ "_id" : ObjectId("4f30a2944d203c27d8f4c587"), "hash" : { "call_id" : "5555" }, "something" : "DDD" }
{ "_id" : ObjectId("4f30a2994d203c27d8f4c588"), "hash" : { "call_id" : "5555" }, "something" : "EEE" }

i uruchomienie tej mapy zredukuj

> db.disTest.mapReduce(_map,_reduce, {out: { inline : 1}})
{
    "results" : [
        {
            "_id" : "1234",
            "value" : {
                "doc" : [
                    {
                        "_id" : ObjectId("4f30a27c4d203c27d8f4c584"),
                        "hash" : {
                            "call_id" : "1234"
                        },
                        "something" : "AAA"
                    }
                ]
            }
        },
        {
            "_id" : "5555",
            "value" : {
                "doc" : [
                    {
                        "_id" : ObjectId("4f30a2944d203c27d8f4c587"),
                        "hash" : {
                            "call_id" : "5555"
                        },
                        "something" : "DDD"
                    }
                ]
            }
        }
    ],
    "timeMillis" : 2,
    "counts" : {
        "input" : 5,
        "emit" : 5,
        "reduce" : 2,
        "output" : 2
    },
    "ok" : 1,
}

Otrzymujesz pierwszy dokument z odrębnego zestawu. Możesz zrobić to samo w mongoid, najpierw skonkretyzuj funkcje map/reduce i wywołaj mapreduce w ten sposób

  MyObject.collection.mapreduce(_map,_reduce,{:out => {:inline => 1},:raw=>true })

Mam nadzieję, że to pomoże




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Utrzymywanie kolejności żądań http w pętli for w javascript

  2. Jak przechowywać dane w MongoDb za pomocą modelu wodospadu mongoose i asynchronicznego?

  3. Jak znaleźć osadzone dokumenty Mongoid na podstawie wielu kryteriów?

  4. Facebook-paszport z JWT

  5. Wysyłanie zapytań o rozmiar tablicy wewnętrznej w MongoDB