Original Query Works but Adding Additional $or Condition Fails
I have a MongoDB query that successfully returns 2 results:
{
"state": "Review",
"type": "Test",
"subtype": { "$in": ["dr_visit", "annual_physical", "psychiatric_visit"] },
"archived": false,
"data.visitInformation.dateOfVisit": { "$gte": "2024-11-19T00:00:00.000Z" },
"deleted": false,
"$or": [
{ "account": "5dad84a4de014f0011999e27" },
{ "referral.user": "66cd7113e3887e0015522f05", "referral.accepted": true },
{ "referral.account": "5dad84a4de014f0011999e27", "referral.accepted": true }
]
}
This query works and retrieves the expected 2 documents.
Now, I want to modify the query to include another condition: check either data.visitInformation.dateOfVisit
or data.overview.visitDate
in the $or
clause. These two fields are never present in the same document—they are part of different document types. However, when I try the following query, it returns no results:
{
"state": "Review",
"type": "Test",
"subtype": { "$in": ["dr_visit", "annual_physical", "psychiatric_visit"] },
"archived": false,
"deleted": false,
"$and": [
{
"$or": [
{ "account": "5dad84a4de014f0011999e27" },
{ "referral.user": "66cd7113e3887e0015522f05", "referral.accepted": true },
{ "referral.account": "5dad84a4de014f0011999e27", "referral.accepted": true }
]
},
{
"$or": [
{ "data.visitInformation.dateOfVisit": { "$gte": "2024-11-19T00:00:00.000Z" } },
{ "data.overview.visitDate": { "$gte": "2024-11-19T00:00:00.000Z" } }
]
}
]
}
Problem
This query returns no results even though the original query works. I suspect it’s related to how MongoDB handles $and
and $or
combinations, especially since data.visitInformation.dateOfVisit
and data.overview.visitDate
belong to different document types.
Question
Is there a way to achieve the desired result, where the query:
- Matches documents with
data.visitInformation.dateOfVisit
ordata.overview.visitDate
, - And satisfies the
$or
conditions for theaccount
orreferral
fields?
Any suggestions or insights are much appreciated!
2
Answers
MongoDB doesn’t require both sets of conditions to be true at the same time. Instead, we’ll combine everything into a single $or at the top leve
What’s Happening Now:
The top-level $or says "either this set of conditions matches, or that set of conditions matches."
The first set of conditions checks the account or referral fields.
The second set checks the date fields (dateOfVisit or visitDate).
This way, if a document matches either the account/referral conditions or the date conditions, it will be returned.
Why This Works:
By grouping the two $or conditions into one $or at the top level, MongoDB is no longer trying to match both the account/referral and the date conditions at the same time. It just needs to match one of those sets of conditions.
Bottom Line:
This should allow the query to return documents that satisfy either the account/referral criteria or the date criteria. Try this query and see if it works as expected!
Let me know if that clears things up or if you run into any issues!
In the comments, you have specified that the properties
data.visitInformation.dateOfVisit
anddata.overview.visitDate
store data as date data type. In the query, a string is provided as comparison for$gte
. This compares different data types, which does not lead to the expected results in the vast majority of the cases.Instead of providing strings for the
$gte
comparison, use the ISODate helper, e.g.ISODate('2024-11-19T00:00:00.000Z')
. This way, only date data types are compared with one another.