简体   繁体   中英

How to find all elements of a collection in an array that matches two conditions

I've been looking at this documentation , and I tried to implement it here:

customers.find({'name':tenantName,'scripts.author':author},'scripts',function(err,data2){

But this doesn't find what I want it to find. and I get back every element of scripts whether scripts.author matches or not.

What am I doing wrong?

My data looks like this

{
name: "something"
scripts:[
    {author:"something", data:"data"},
    {author:"something else" data:"data2"},
    {author:"something", data:"data3"}
        ]
}

I'd like to get all the scripts where author matches what I give it

There are a few things wrong here for you to understand about matching in queries like this. First of all, what your were trying to do was this:

customer.find(
    { "name":tenantName, "scripts.author": author },
    { "scripts.$" },
    function(err,data2) {

      // work here
})

And that would use the positional $ operator to match the element. But the problem here is that will only match the first element of the array. This is covered in the documentation. The result will be like this:

{ "scripts" : [  {  "author" : "something",  "data" : "data" } ] }

If you need to match muliple elements, then you need to use the aggregate function in order to filter the array contents:

customer.aggregate([

    // Match just the documents you want
    { "$match": { "name": tenantName, "scripts.author": author } },

    // Unwind the array
    { "$unwind": "$scripts" },

    // Match to filter just the array elements
    { "$match": { "scripts.author": author } },

    // Push back the array elements
    { "$group": {
        "_id": "$_id",
        "name": { "$first": "$name" },
        "scripts": { "$push": "$scripts" }
    }}

],
function(err,result) {

})

And the results there will be the two elements that match "something" as the author .

Why all of this? Well there is the limitation on what can be done with projection that was mentioned. But the main reason is that you are not matching elements in the array , but you are matching the document that "contains" the matching elements in the array.

So if you really want to filter the results, this is how you do it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM