nialloc
nialloc

Reputation: 1193

Complex Logic quires on simple mongo document

I am battling with forming complex logic queries on very basic data types in mongo. Essentially I can have millions of user attributes so my basic mongo document is:

{
   name: "Gender"
   value: "Male"
   userId : "ABC123"
}

{
   name: "M-Spike"
   value: 0.123
   userId : "ABC123"
}

What I would like to do is search for things like findAll userId where {name : "Gender, value: "Male"} AND { name : "m-spike", value : { $gt : 0.1} }

I have tried using the aggregation framework but the complexity of the queries is limited, basically I was ORing all the criteria and counting the results by sampleId (which replicated a rudimentary AND)

Upvotes: 2

Views: 388

Answers (1)

Asya Kamsky
Asya Kamsky

Reputation: 42352

I can see a way to do it for N being the number of attributes you want to query about (N being 2 in your example). Try something like this:

 db.collection.aggregate(
      [  {  $match:  {$or: [ 
                        {"name":"M-Spike","value":{$gt:.1}},
                        {"name":"Gender","value":"Male"}
                           ] 
                     } 
         },   
         {  $group: { _id:"$userId",total:{$sum:1}}  
         },
         { $project: { _id:1, 
                       matchedAttr : { $eq: ["$total",2] }   
                     } 
         }
      ]
 )

You will get back:

{
    "result" : [
        {
            "_id" : "XYZ123",
            "matchedAttr" : false
        },
        {
            "_id" : "ABC123",
            "matchedAttr" : true
        }
    ],
    "ok" : 1
}

Now, if you had 2 conditions you matched via "$or" then you get back true for _id that matched both of them. So for five conditions, your $match: $or array will have five conditional pairs, and the last $project transformation will be $eq: ["$total",5]

Built in to this solution is the assumption that you cannot have duplicate entries (i.e. _id cannot have "M-Spike":.5 and also "M-Spike":.2. If you can, then this won't work.

Upvotes: 0

Related Questions