to compare two fields of the same collection - mongodb

I want to compare two fields of the same collection (Mysql query example "SELECT * FROM table AS t WHERE t.field1 > t.filed2;") in mongodb with cakephp. I cannot use '$where' and aggregate of mongodb as I am also using other operators of mongodb like $or, $and and etc. And also I am using find of mongodb.
Ex: Collection have two fields integer fields per_day_budget and today_spent and I want to get the list of records where today_spent is less than or equal to per_day_budget. I hope this will you to better understand my query.
Kindly suggest solution for the same.

You can try:
db.collection.find({ this.today_spent : {$lte : this.per_day_budget}});

Related

MongoDB sort performance when used with $in query

I have a collection product in my DB. Below is one sample document:
{
"sku_id":"12345678",
"priduct_name":"milk",
"product_rank":3,
"product_price": 2.4
}
There are 100k such unique documents in our collection.
I want to query this collection using $in query, as shown below.
db.product.find({"sku_id" :{$in :["12345678","23213"]}}).sort( { product_rank: 1 } )
Our requirement is to search documents based on $in query and sort any field in document(asc or desc).
I have created both forward and reverse index on all fields for this collection.
Note: This sku_id array inside $in query can have 1000+ sku_ids.
My doubt is if I use the filter like $in with an array of sku_id and get the sorted result on any field, will it use the index for sorting or will it sort at query time?
Mongo allows you to find out if a query will use an index. As the find operation returns a cursor you can extend the method chain to include an explain() command which does exactly what you need. (suggest you use db.product.find(...).sort(...).explain('executionStats'))
Will it use the index for sorting or will it sort at query time?
The index created on the product_rank will be used in the query but, not an index on the sku_id alone. Instead create a compound index with both product_rank and sku_id(asc and desc).

MongoDB $regex with $in clause

I need a mongodb query something like
db.getCollection("xyz").find({"_id" : {$regex : {$in : [xxxx/*]}}})
My Use case is -- I have a list of Strings such as
[xyz/12/poi, abc/98/mnb, ytn/65/tdx, ...]
The ids that are there in the collection(test) are something like
xyz/12/poi/2019061304.
I will get the values like xyz/12/poi from the input list, the other part of the id being yyyymmddhh format.
So, I need to go to the collection and find all the documents matching the input list with the ID of the documents in the test collection.
I can retrieve the documents individually but that does not seem to be a feasible option as the size of the input list is more than 10000.
Can you guys suggest a more feasible solution. Thanks in advance.
I tried using $in with $regex. But it seems mongodb does not support that. I have also tried pattern matching but even that is not feasible for me. Can you please suggest an alternative to using $in with $regex in mongodb.
Expected result could be an aggragate query/a normal query so that we hit the database only once and get the desired output rather than hitting the db for 10000 odd times.

Order of Fields in Mongo Query vs Ordered Checked In

Say you're querying documents based on 2 data points. One is a simple bool parameter, and the other is a complicated $geoWithin calculation.
db.collection.find( {"geoField": { "$geoWithin" : ...}, "boolField" : true} )
Will mongo reorder these parameters, so that it checks the boolField 1st, before running the complicated check?
MongoDB uses indexes like any other DBs. So the important thing for mongoDB is if any query fields has an index or not, not the order of query fields. At least there is no information in their documentation that mongoDB try to checks primitive query fields first. So for your example if boolField has an index mongoDB first check this field and eliminate documents whose boolField is false. But If geoField has an index then mongoDB first execute query on this field.
So what happens if none of them have index or both of them have? It should be the given order of fields in query because there is no suggestion or info beside of indexes in query optimization page of mongoDB. Additionally you can always test your queries performances with just adding .explain("executionStats").
So check the performance of db.collection.find( {"geoField": { "$geoWithin" : ...}, "boolField" : true} ) and db.collection.find( { "boolField" : true, "geoField": { "$geoWithin" : ...} } ). And let us know :)
To add to above response, if you want mongo to use specific index you can use cursor.hint . This https://docs.mongodb.com/manual/core/query-plans/ explains how default index selection is done.

how to prevent a document getting indexed during full import?

I have a mongodb collection which i would like to index on solr using data import handler . But i don't want the documents with foodType(a field in document) as variant to get indexed during full import how to do it?
If you have the query to get the documents from the MongoDB.
Then modify that query by adding a filtering condition.
This filter will not retreive the data from mongoDB where the documents has foodType.
e.g
db.collection.find({ "fieldToCheck" : { $exists : true, $ne : null } })
You can add some conditions as above in your query and restrict the data from being indexed in solr.
In the data-config the query is missing and that is the reason its getting all the documents from mongoDB. If you add the query with correct criteria it will retrive selected documents.
For more on the mongo Query please refer the link below
MOngoDB reference link

Mongodb: return matched filters when using $or in find()

Suppose I am doing a query in Mongodb like this
db.user.find({$or : [{"field1" : "abc"}, {"field2" : "def"}, {"field3" : "ghi"}]})
And a number of documents are returned. What is the easiest way to know which one (or multiple) of the three filters is matched for each document returned? By "easiest", I do not wish to add more executions of find()'s.
Thanks.
There is no such option to solve this on the MongoDB query layer. Likely you want to perform individual queries instead one big $or query in order to solve your problem.