I've got a MongoDB collection where a particular string may appear in any of a number of fields:
{"_id":1, "field1": "foo", "field2": "bar", "field3": "baz", "otherfield": "stuff"},
{"_id":2, "field1": "bar", "field2": "baz", "field3": "foo", "otherfield": "morestuff"},
{"_id":3, "field1": "baz", "field2": "foo", "field3": "bar", "otherfield": "you get the idea"}
I need to query so that I am returned all records where any one of a set of fields is equal to any value in an array ... basically, if I have ["foo","bar"]
I need it to match if either of those strings are in field1 or field2 (but not any other field).
Obviously I can do this with a series of multiple queries
db.collection.find({"field1":{"$in":["foo","bar"]}})
db.collection.find({"field2":{"$in":["foo","bar"]}})
etc., and I've also made a very large $or query that concatenates them all together, but it seems far too inefficient (my actual collection needs to match any of 15 strings that can occur in any of 9 fields) ... but I'm still new to nosql DBs and am not sure of the best paradigm I need to use here. Any help is greatly appreciated.
To find the multiple values, we can use the aggregation operations that are provided by MongoDB itself. When we have large data set and we only want to find the documents of a particular value in that situation we use aggregation operations.
Find Multiple Conditions Using the $or Operator The or operator in MongoDB is used to select or retrieve only documents that match at least one of the provided phrases. You can also use this operator in a method like a find() , update() , etc., as per the requirements.
You can try something like below. Make use of $map to project the required fields and use $filter to filter matching Node and Collection and $arrayElemAt to change the array to object to match the expected output format.
In MongoDB, we can apply the multiple conditions using the and operator. By applying the and operation we will select all the documents that satisfy all the condition expressions. We can use this operator in methods like find(), update() , etc as per the requirement.
try
db.collection.find(
// Find documents matching any of these values
{$or:[
{"field1":{"$in":["foo","bar"]}},
{"field2":{"$in":["foo","bar"]}}
]}
)
also refer to this question
Found another answer through poring over the documentation that seems to hit a sweet spot -- text indexes.
db.collection.ensureIndex({"field1":"text","field2":"text"})
db.records.runCommand("text",{search:"foo bar"})
When I run my actual query with many more strings and fields (and about 100,000 records), the $or/$in
approach takes 620 milliseconds while the text index takes 131 milliseconds. The one drawback is that it returns a different type of document as a result; luckily the actual documents are a parameter of each result object.
Thanks to those who took the time to make suggestions.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With