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

Mongodb, обобщена заявка с $lookup

За всеки конкретен документ за лице можете да използвате populate() функция като

var query = mongoose.model("person").find({ "name": "foo" }).populate("projects.tags");

И ако искате да търсите хора, които имат някакъв маркер с 'MongoDB' или 'Node JS' например, можете да включите опцията за заявка в populate() претоварване на функцията като:

var query = mongoose.model("person").find({ "name": "foo" }).populate({
    "path": "projects.tags",
    "match": { "en": { "$in": ["MongoDB", "Node JS"] } }
});

Ако искате всички тагове да съществуват в "project.tags" за всички хора, тогава рамката за агрегиране е правилният начин. Помислете за стартиране на този конвейер върху колекцията от хора и да използвате $lookup оператор, за да извърши ляво присъединяване към колекцията от етикети:

mongoose.model('person').aggregate([
    { "$unwind": "$projects" },
    { "$unwind": "$projects.tags" },
    {
        "$lookup": {
            "from": "tags",
            "localField": "projects.tags",
            "foreignField": "_id",
            "as": "resultingTagsArray"
        }
    },
    { "$unwind": "$resultingTagsArray" },
    {
        "$group": {
            "_id": null,
            "allTags": { "$addToSet": "$resultingTagsArray" },
            "count": { "$sum": 1 }
        }
    }
 ]).exec(function(err, results){
    console.log(results);
 })

За всеки конкретен човек след това приложете $match pipeline като първа стъпка за филтриране на документите:

mongoose.model('person').aggregate([
    { "$match": { "name": "foo" } },
    { "$unwind": "$projects" },
    { "$unwind": "$projects.tags" },
    {
        "$lookup": {
            "from": "tags",
            "localField": "projects.tags",
            "foreignField": "_id",
            "as": "resultingTagsArray"
        }
    },
    { "$unwind": "$resultingTagsArray" },
    {
        "$group": {
            "_id": null,
            "allTags": { "$addToSet": "$resultingTagsArray" },
            "count": { "$sum": 1 }
        }
    }
 ]).exec(function(err, results){
    console.log(results);
 })

Друго решение, ако използвате версии на MongoDB>=2.6 или <=3.0, които нямат поддръжка за $lookup операторът трябва да попълни резултатите от агрегирането като:

mongoose.model('person').aggregate([
    { "$unwind": "$projects" },
    { "$unwind": "$projects.tags" },    
    {
        "$group": {
            "_id": null,
            "allTags": { "$addToSet": "$projects.tags" }
        }
    }
 ], function(err, result) {
    mongoose.model('person')
    .populate(result, { "path": "allTags" }, function(err, results) {
        if (err) throw err;
        console.log(JSON.stringify(results, undefined, 4 ));
    });
});


  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. node.js mongodb изберете документ по _id node-mongodb-native

  2. mongodb агрегиране php

  3. Съвети за управление на архивиране на MongoDB за разчленени клъстери

  4. Как ClusterControl извършва автоматично възстановяване и отказ на база данни

  5. Твърде много отворени файлове, като същевременно осигурите индекс mongo