问题
My basic structure is I have User object with a session object that contains a subjectId and an hourly price.
User{
defaultHourly: Number,
subjects{
[
id: String,
hourly: Number
]
}
}
I use elemMatch like this:
query.elemMatch("subjects", {
"id": { $in: subjects },
"$or": [
{ "hourly": { $eq: null } }, // this is my issue
{
"$and": [
{ "hourly": { $ne: null } },
{ "hourly": { $gte: price.low, $lte: price.high } }
]
}
]
});
the first part of elemMatch makes sure that the subjectId I want is in the array of subjects. Then I want to filter by price. if a User has null in the hourly field, I want to then compare the defaultHourly to price.low and price.high.
The issue is that defaultHourly is not a field in subjects, but is a field in the parent of subjects so I'm not sure how to access it.
I want to write:
"$or": [
{
"$and": [
{ "hourly": { $eq: null } },
{ "defaultHourly": { $gte: price.low, $lte: price.high } } //this doesnt work because default hourly is not a field.
]
},
{
"$and": [
{ "hourly": { $ne: null } },
{ "hourly": { $gte: price.low, $lte: price.high } }
]
}
]
});
How can I do this multilevel comparison?
回答1:
You write the condition outside of the $elemMatch, and put the $or at the top level of the document. This allows each "set" of conditions to apply:
User.find({
"$or": [
{
"defaultHourly": { "$gte": price.low, "$lte": price.high },
"subjects": {
"$elemMatch": {
"id": { "$in": subjects },
"hourly": { "$eq": null }
}
}
},
{
"subjects": {
"$elemMatch": {
"id": { "$in": subjects },
"hourly": { "$gte": price.low, "$lte": price.high }
}
}
}
]
})
Also note the $ne is not needed, since the "range" comparison would actually negate null
since it simply would not be "greater than" an actual numeric value.
In addition, note that ALL MongoDB query expressions are already AND conditions, such as the $gte and $lte on the same property. So even though it's not required, the $ne can also be written in as:
"hourly": { "$gte": price.low, "$lte": price.high, "$ne": null }
Which removes any need for an explicit $and.
来源:https://stackoverflow.com/questions/44786973/use-or-with-elemmatch-and-condition-outside-of-array