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

Mongoose изберете полета за поддокумент

Ето как MongoDB обработва основната проекция с елементи от масив. Въпреки че можете да направите нещо подобно:

Model.findOne({}, { "comments.upvotes": 1 },function(err,doc) {

})

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

За да получите това, което искате, имате нужда от разширените възможности за манипулиране на документи, предлагани от рамка за агрегиране . Това ви дава повече контрол върху начина на връщане на документите:

Model.aggregate(
    [
        // Match the document containing the array element
        { "$match": { "comments._id" : oid } },

        // Unwind to "de-normalize" the array content
        { "$unwind": "$comments" },

        // Match the specific array element
        { "$match": { "comments._id" : oid } },

        // Group back and just return the "upvotes" field
        { "$group": {
            "_id": "$_id",
            "comments": { "$push": { "upvotes": "$comments.upvotes" } }
        }}
    ],
    function(err,docs) {


    }
);

Или в съвременните версии на MongoDB след 2.6 можете дори да направите това:

Model.aggregate(
    [
        { "$match": { "comments._id" : oid } },
        { "$project": {
            "comments": {
                "$setDifference": [
                    { "$map": {
                        "input": "$comments",
                        "as": "el",
                        "in": {
                            "$cond": [
                                { "$eq": [ "$$el._id", oid ] },
                                { "upvotes": "$$el.upvotes" },
                                false
                            ]
                        }
                    }},
                    [false]
                ]
            }}
        }}
    ],
    function(err,docs) {

    }
)

И това използва $map и $setDifference оператори за извършване на "вградено" филтриране на съдържанието на масива, без първо да се обработва $unwind етап.

Така че, ако искате повече контрол върху това как се връща документът, тогава рамката за агрегиране е начинът да го направите, когато работите с вградени документи.




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Как да върна резултатите от Mongoose от метода за намиране?

  2. Как да разрешите com.mongodb.spark.exceptions.MongoTypeConversionException:Не може да прехвърля... Java Spark

  3. ServerSelectionTimeoutError errno 11001 getaddrinfo неуспешно python

  4. използвайте глобална променлива за споделяне на db между модула

  5. Файловете на журнала присъстват в директорията на журнала, но стартират без активирано журналиране