简体   繁体   中英

Mongoose distinct condition not working

I'm using mongoose to query a MongoDB using following scheme:

var File = mongoose.model('File',{
    size: Number,
    type: String,
    filename: String,
    path: String,
    taxonomies:[{
        tags:[{
            name:String,
            'tag':String
        }],
        name: String
    }]
});

Now I want to do a distinct query as follows:

File.distinct('taxonomies.tags.tag', {'taxonomies.name':'AM'},function(error, tags){
     if(err)
           res.send(err);

     console.log("All distinct tags", tags);
})

to get all unique tags from all files where the name of the taxonomy is 'AM'. The problem is that the query above returns all tags, including those with a different taxonomies.name. Without the condition, it just works as it should.

Do I have a syntactic error in here, or am I misunderstanding how distinct works?

Update (More examples) Each document has a taxonomy with name SM and one with name AM, something like

taxonomies: [{
            tags: [
            {
                name:"Type",
                'tag':kind
            }, {
                name:"Language",
                'tag':lang
            },
            {
                name:"Code",
                "tag":code
            }],
            name:'AM'
        }, {
            name:'SM',
            tags:[{
                name:"Sales",
                'tag':'has to be sold'
            },{
                name:"Personal filter",
                'tag':'temp'
            }]
        }]

When I execute the query mentioned above, I get as a result:

All distinct tags [ '4007', 'fr', 'has to be sold', 'temp', 'wol', '16104', 'en' ]

while 'temp' and 'has to be sold are from SM, not AM.

I want as a result only the ones wehre taxonomies.name = 'AM', across all documents, without duplicates

The query selection is selecting documents , not elements from the array:

{'taxonomies.name':'AM'}

That criteria will select the entire document.

As a result, all items in both arrays are considered as valid for the distinct operation. If you only want subsets to be considered, you'll either need to use the aggregation framework to filter, or modify your documents so that the two taxonomies are not stored in the same document.

If you used the aggregation framework instead of the distinct command, there are a lot of options you could use to gather the distinct values:

db.test.aggregate({$unwind: "$taxonomies" },  
      { $group : 
          {  _id: "$taxonomies.name", 
             tags: { $addToSet: "$taxonomies.tags" } }} )

That should group on both SM and AM (and any others):

 [
     {
             "_id" : "SM",
             "tags" : [
                     [
                             "d1",
                             "e1"
                     ],
                     [
                             "d",
                             "e"
                     ]
             ]
     },
     {
             "_id" : "AM",
             "tags" : [
                     [
                             "a1",
                             "b1",
                             "c1"
                     ],
                     [
                             "a",
                             "b",
                             "c"
                     ]
             ]
     }
]

You could use $match to filter on a particular name as well.

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