sql >> Database >  >> NoSQL >> MongoDB

Rails &Mongoides unieke resultaten

U kunt het document (of de subset) niet eenvoudig retourneren door de distinct te gebruiken. Volgens de documentatie het retourneert alleen de afzonderlijke reeks waarden op basis van de gegeven sleutel. Maar u kunt dit bereiken door kaartverkleining te gebruiken

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

De bovenstaande code spreekt voor zich, op de kaartfunctie groepeer ik deze op sleutel hash.call_id en het hele document terugsturen zodat het kan worden verwerkt door de functie te verminderen.

Bij de functie verminderen, loop je gewoon door de gegroepeerde resultatenset en kies je slechts één item uit de gegroepeerde set (tussen de meerdere dubbele sleutelwaarden - verschillende simulatie).

Maak tot slot wat testgegevens

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

en het uitvoeren van deze kaart verminderen

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

U krijgt het eerste document van de afzonderlijke set. Je kunt hetzelfde doen in mongoid door eerst de map/reduce-functies te stringen en mapreduce op deze manier aan te roepen

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

Ik hoop dat het helpt




  1. Herstel van verbroken verbinding in redis pub/sub

  2. Probeer met $regex meerdere velden tegelijk te vinden in Mongodb

  3. Mongoose-selectievelden (geneste)

  4. Voer MongoDump / MongoRestore uit in C #