When I search for documents containing title 'Apple' as such:
db.getCollection('items').find({title: {$regex: 'Apple'}})
The documents with title containing 'Apple' are returned as expected
When I search for documents where priceA is less than priceB as such:
db.getCollection('items').find({"$where":"this.priceA < this.priceB"})
The documents where priceA is less than priceB are returned as expected.
However, when I try to do both together as such:
db.getCollection('items').find({title: {$regex: 'Apple'}},
{"$where":"this.priceA < this.priceB"})
Only the _id field is returned, and it's really all the documents in my collection and the two filters above are not applied at all:
How do I apply both filters?
Your query is wrong try this. You are passing the second condition wrong in projection method check this out for more details
Mongodb find() method takes 3 arguments
condition:{title: {$regex: 'Apple'},"$where":"this.priceA < this.priceB"}
Projection:
By default t you wont specify any thing in projection it will return you the entire document but if you want only specific details you can pass it like {name:1,email:1}
Options:
sample example is{sort:1,limit:1}
db.getCollection('items').find({title: {$regex: 'Apple'},"$where":"this.priceA < this.priceB"}, {})
Related
Currently I could filter with this MongoDb query
db.getCollection("entity").find(
{
"NameDetails.Name.0.NameValue.0.EntityName" : /ABC/
}
);
How do I loop through all the Name and then all the NameValue to search for /ABC/? If any of it matches, it returns as result.
You need to either use elemMatch or unwind.
If you know that it would match one element always, use elemMatch
or
If you want all the matching elements in the array, go for unwind then group.
{
$or:[{TextField1:{$eq:"DX93E6XX6R"}}],
$or:[{TextField1:{$eq:"N4JXFTNP64"}}]
}
There are two documents in the collection. One with a "TextField1" value equal to the first expression and one with the same field equal to the second expression.
My thought was:
Find all documents where TextField1 equals "DDX93E6XX6R" AND TextField1 equals "N4JXFTNP64"
It's not a sensible query because you can't have two fields named $or in the same object so only the second one will be used (overwriting the first one). And an $or with one element is the same as just that element.
So it's the same as:
{TextField1:{$eq:"N4JXFTNP64"}}
Which is the same as:
{TextField1: "N4JXFTNP64"}
Which is:
Find all documents where TextField1 equals "N4JXFTNP64"
If you're looking to match documents with either value, then your statement could be either:
{$or: [{Textfield1: "foo1"}, {Textfield1: "foo2"}]}
or...
{Textfield1: {$in: ["foo1", "foo2"]}}
I have two collections and I want to get fields from both, so I'm using $lookup in an aggregation pipeline.
This works fine and returns all the documents with an extra field, an array with 0 or 1 elements (an object). If 0 elements, it means that the JOIN(in SQL world) didn't return anything. If 1 element, it means that there was a match and the element in an object with the fields of the second collection.
Now that I have those results, I'd like to use $match in order to filter some of the results.
In order to use $match I first want to use $unwind on that new extra field in order to extract the array. The problem is once I insert the $unwind stage, the result of the query is a single document.
Why is this happening? How can I $unwind and then $match all the documents I got from the $lookup stage?
assume we have documents after lookup:
{doc:{_id:1, lookupArray:[{doc:1},{doc:2}]}}
and
{doc:{_id:2, lookupArray:[/* empty */]}}
when we $unwind without any options we will get:
{doc:{_id:1, lookupArray:{doc:1}}}
{doc:{_id:1, lookupArray:{doc:2}}}
null
and when we specify
{ $unwind: { path: "$array", preserveNullAndEmptyArrays: true } }
then we will get:
{doc:{_id:1, lookupArray:{doc:1}}}
{doc:{_id:1, lookupArray:{doc:2}}}
{doc:{_id:2, lookupArray:[/* empty */]}}
So when you want to perform a search for a value doc from lookupArray, $match will look like this:
{$match:{'lookupArray.doc':2}}
Any comments welcome!
I have a mongodb query where i want to get documents if a field has particular value.
db.collection.find({key:{$in:['value1','value2']}}) if i run above command i get documents containing either 'value1' or 'value2'. but lets just say there are no values. and i search db.collection.find({key:{$in:[]}}), nothing is displayed. and db.collection.find({key:{$in:[*]}}) gives unexpected token* which wild card do i use in $in to show all results.?
I think this is logically consistent behavior for $in. The query
db.collection.find({ "key" : { "$in" : [] } })
could be translated as "find all the documents where the value of key is one of the values contained in the array []". Since there are no values in the array [], there are no matching documents. If you want to find all of the extant values for key, use .distinct to return them as an array:
db.collection.distinct("key")
.distinct will use an index if possible.
If you want a query to match all documents, omit the query selector from .find:
db.collection.find()
as suggested in the comments.
I have a mongo DB collection that looks something like this:
{
{
_id: objectId('aabbccddeeff'),
objectName: 'MyFirstObject',
objectLength: 0xDEADBEEF,
objectSource: 'Source1',
accessCounter: {
'firstLocationCode' : 283,
'secondLocationCode' : 543,
'ThirdLocationCode' : 564,
'FourthLocationCode' : 12,
}
}
...
}
Now, assuming that this is not the only record in the collection and that most/all of the documents contain the accessCounter subdocument/field how will I go with selecting the x first documents where I have the most access from a specific location.
A sample "query" will be something like:
"Select the first 10 documents From myCollection where the accessCounter.firstLocationCode are the highest"
So a sample result will be X documents where the accessCounter. will be the greatest is the database.
Thank your for taking the time to read my question.
No need for an aggregation, that is a basic query:
db.collection.find().sort({"accessCounter.firstLocation":-1}).limit(10)
In order to speed this up, you should create a subdocument index on accessCounter first:
db.collection.ensureIndex({'accessCounter':-1})
assuming the you want to do the same query for all locations. In case you only want to query firstLocation, create the index on accessCounter.firstLocation.
You can speed this up further in case you only need the accessCounter value by making this a so called covered query, a query of which the values to return come from the index itself. For example, when you have the subdocument indexed and you query for the top secondLocations, you should be able to do a covered query with:
db.collection.find({},{_id:0,"accessCounter.secondLocation":1})
.sort("accessCounter.secondLocation":-1).limit(10)
which translates to "Get all documents ('{}'), don't return the _id field as you do by default ('_id:0'), get only the 'accessCounter.secondLocation' field ('accessCounter.secondLocation:1'). Sort the returned values in descending order and give me the first ten."