sql >> Database teknologi >  >> NoSQL >> MongoDB

Rails &Mongoid unikke resultater

Du kan ikke blot returnere dokumentet (eller delmængden) ved at bruge distinkten. I henhold til dokumentationen det returnerer kun den distinkte matrix af værdier baseret på den givne nøgle. Men du kan opnå dette ved at bruge 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;
}

Ovenstående kode er selvforklarende, på kortfunktionen grupperer jeg den efter nøglen hash.call_id og returnerer hele dokumentet, så det kan behandles ved at reducere funktionen.

Ved reduktionsfunktionen skal du blot gå gennem det grupperede resultatsæt og kun vælge ét element fra det grupperede sæt (blandt de multiple dubletnøgleværdier - særskilt simulering).

Lav endelig nogle testdata

> 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" }

og køre dette kort reducere

> 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,
}

Du får det første dokument af det særskilte sæt. Du kan gøre det samme i mongoid ved først at strenge kort-/reducer-funktionerne og kalde mapreduce på denne måde

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

Håber det hjælper




  1. mislykkedes med Modtaget hjerteslag fra medlem med samme medlems-id som os selv:0

  2. Mongoexport fejlparsing forespørgsel

  3. Brug af multiplikationsaggregation med MongoDB

  4. Express node.js-controlleren venter ikke på datamanipulation og returnerer gamle data