Marco Tribuzio
Marco Tribuzio

Reputation: 103

Multiple filters in MongoDB query

I have this document

{
    "_id" : ObjectId("6afda532e9a0e3838537c71a"),
    "VersionId" : 0,
    "NodeId" : [ 
        {
            "NodeId" : 0,
            "Host" : "127.0.0.1",
            "DatabaseName" : "NodeId0",
            "Collection" : [ 
                {
                    "CollectionId" : 0,
                    "CollectionName" : "Codice0"
                }, 
                {
                    "CollectionId" : 1,
                    "CollectionName" : "Codice1"
                }
            ]
        }, 
        {
            "NodeId" : 1,
            "Host" : "127.0.0.2",
            "DatabaseName" : "NodeId1",
            "Collection" : [ 
                {
                    "CollectionId" : 1,
                    "CollectionName" : "Codice1"
                }
            ]
        }
    ]
}

and would like to extract only 1 filed of nodeId and 1 field for CollectionId, is it possible?

The returned document should have this structure:

{
    VersionId: 0,
    NodeId: {
        NodeId: 0,
        Collection: {
          CollectionId: 0,
          CollectionName: Codice0
        }
    }
}

I tried this query, without result:

let queryDatabasePath = collezioneDbPath.aggregate([
    { $match: { "VersionId" : versionId } },
    { $project: {
        NodeId : { $filter: {
            input: '$NodeId',
            as: 'prova',
            cond: {$and: [
                {$eq: ['$$prova.NodeId' , nodeId ]},
                {$filter: {
                    input:'$prova',
                    as: 'prova1',
                    cond: {$eq: ['$$prova1.Collection.CollectionId', collectionId]}
                }}

            ]}

        } },
        //"NodeId.Collection.CollectionId" : 1,
        _id: 0
    } }
], function (err, res) {
    console.log(res);
});

Upvotes: 2

Views: 16502

Answers (2)

s7vr
s7vr

Reputation: 75914

You can try something like below. Make use of $map to project the required fields and use $filter to filter matching Node and Collection and $arrayElemAt to change the array to object to match the expected output format.

aggregate([{
    $match: {
        "VersionId": 0
    }
}, {
    $project: {
        NodeId: {
            $arrayElemAt: [{
                $map: {
                    input: {
                        $filter: {
                            input: "$NodeId",
                            as: "prova",
                            cond: {
                                $eq: ["$$prova.NodeId", 0]
                            }
                        }
                    },
                    as: "nd",
                    in: {
                        "NodeId": "$$nd.NodeId",
                        "Collection": {
                            $arrayElemAt: [{
                                $filter: {
                                    input: "$$nd.Collection",
                                    as: "proval",
                                    cond: {
                                        $eq: ["$$proval.CollectionId", 0]
                                    }
                                }
                            }, 0]
                        }
                    }
                }
            }, 0]
        },
        _id: 0
    }
}])

Upvotes: 3

Ankur Rupapara
Ankur Rupapara

Reputation: 136

If you do with "VersionId" or with _Id then result appropriate like following manners:

db.getCollection('a').aggregate([
{$unwind: '$NodeId'},
{$unwind: '$NodeId.Collection'},
{$match: {"_id" : ObjectId("5846b47c8254f4cad9acadce"), "VersionId" : 0, "NodeId.NodeId": 0, "NodeId.Collection.CollectionId": 0}}
])

Output like a below data:

{
    "_id" : ObjectId("5846b47c8254f4cad9acadce"),
    "VersionId" : 0,
    "NodeId" : {
        "NodeId" : 0,
        "Host" : "127.0.0.1",
        "DatabaseName" : "NodeId0",
        "Collection" : {
            "CollectionId" : 0,
            "CollectionName" : "Codice0"
        }
    }
}

Upvotes: 4

Related Questions