2

docs:

order1.filter = ['tag1','tag2']
order2.filter = ['tag1','tag2','tag3']

want to get:

query ['tag1','tag2'] -> (only order1)
query ['tag1','tag2','tag3'] -> (order1 and order2)
query ['tag1','tag2','tag3','tag4', etc ] -> (order1 and order2)

and

query ['tag1','tag3'] -> (null)
query ['tag2','tag3'] -> (null)

All values ​​order.filter should be necessarily in the query array

How to do it? Tried directives $all, $in :(

picca
  • 23
  • 3

1 Answers1

0

You can do this with aggregation framework (there is no way to do this with regular find that I know of).

I think this is basically a duplicate so adjusting that code for your fields you get something like:

//sample documents:
> db.docs.find({},{_id:0})
{ "order" : 1, "filter" : [ "t1", "t2" ] }
{ "order" : 2, "filter" : [ "t1", "t2", "t3" ] }
var tagArray = [ "t1", "t2" ];   // array to "match"
db.docs.aggregate( [
    {
        "$project" : {
            "order" : 1,
            "filter" : 1,
            "killFlag" : {
                "$const" : [
                    true,
                    false
                ]
            }
        }
    },
    {
        "$unwind" : "$filter"
    },
    {
        "$unwind" : "$killFlag"
    },
    {
        "$match" : {
            "$nor" : [
                {
                    "filter" : {
                        "$in" : tagArray
                    },
                    "killFlag" : true
                }
            ]
        }
    },
    {
        "$group" : {
            "_id" : "$order",
            "filter" : {
                "$addToSet" : "$filter"
            },
            "killFlag" : {
                "$max" : "$killFlag"
            }
        }
    },
    {
        "$match" : {
            "killFlag" : false
        }
    },
    {
        "$project" : {
            "_id" : 1,
            "filter" : 1
        }
    }
]);
Community
  • 1
  • 1
Asya Kamsky
  • 41,784
  • 5
  • 109
  • 133