I have data im getting using a date range to date and from date :
{
$match: {
"Date_stock":
{
$gte: new Date(req.body.fromDate),
$lt: new Date(req.body.toDate)
}
}
},
I'm trying to get the difference between each doc's stock like doc 1 stock - doc 2 stock .
I'm using group to get the data:
{ $group: {
"stock":{$toInt:"$stock"}
}}
I dont have any related databases involved . each document has stock number .
how do i subtract the same value from group ?
is this possible to do ?
Related
I am new to MongoDB.
This is my 'masterpatients' collection it has many documents. every documents contain 'visits' array and every visits array contains multiple objects. I want only those object which is satisfied with my input.
I am expecting only below the expected output. if the facility match with my input and visit date range match with my provided input then the query should return only that object as I have given below.
_id:5ef59134a3d8d92e580510fe
flag:0
name:"emicon_test"
dob:2020-06-25T00:00:00.000+00:00
visits:[
{
visit:2020-06-09T10:36:10.635+00:00,
facility:"Atria Lady Lake"
},
{
visit:2020-05-09T10:36:10.635+00:00,
facility:"demo"
}]
_id:5ee3213040f8830e04ff74a8
flag:0
name:"xyz"
dob:1995-06-25T00:00:00.000+00:00
visits:[
{
visit:2020-05-01T10:36:10.635+00:00,
facility:"pqr"
},
{
visit:2020-05-15T10:36:10.635+00:00,
facility:"demo"
},
{
visit:2020-05-09T10:36:10.635+00:00,
facility:"efg"
}]
My query input parameters is facility='demo' and visit date range is from '1st May 2020' to '10th May 2020'
output expected:
_id:5ef59134a3d8d92e580510fe
flag:0
name:"emicon_test"
dob:2020-06-25T00:00:00.000+00:00
visits:[
{
visit:2020-05-09T10:36:10.635+00:00,
facility:"demo"
}]
Thanks in advance.
I got an answer.
MasterPatientModel.aggregate([
{
'$unwind':"$visits"
},
{"$match": {"visits.visit": {"$gte": new Date(req.body.facilitySummaryFromdate), "$lte": new Date(req.body.facilitySummaryTodate)
} , "visits.facility": req.body.facilitySummary
}
}
])
You cannot filter the contents of a mongo collection property on the server.
Make visits array into a top level collection/model and you can filter by criteria on the server.
I have a document in mongodb that stores books read by a user.I want to be able to update the data read field given a book_id. How can I do this in a mongo query? Example would be if book_id =111111 update "date_read" to April 5 2020.
{
_id:"1456786576454",
books:[
{
"book_id":"132451",
"date_read":"Jan 20 2020"
},
{
"book_id":"111111",
"date_read":"Feb 5 2020"
}
]
}
I am using one solr query in the code to fetch data collection from solr.
There is a field called 'rank' before I was using in fetch query where condition like "AND (rank:1 OR rank:0)" like this but now I want to change the least number.
For example, my collection doesn't have 0 or 1 but least rank number is 3.
so I want get the list of records having least rank number.
This is my existing query (from logs):
q=category=nfroots AND (rank=1 OR rank=0)
fq=-isLegacyProduct=true
group=true.
Here is mentioned like category= froots,rank= 0 or 1, isLegacyProduct=true, group=true.
I have to make rank= instead 0 or 1 it should be least number.
here is my collection:-
{
"id":"1",
"rank":"1",
"name":"A"
},
{
"id":"2",
"rank":"2",
"name":"A"
}
,
{
"id":"3",
"rank":"2",
"name":"B"
}
,
{
"id":"4",
"rank":"3",
"name":"B"
}
,
{
"id":"5",
"rank":"4",
"name":"B"
}
My Result should be like this :-
{
"id":"1",
"rank":"1",
"name":"A"
},
{
"id":"3",
"rank":"2",
"name":"B"
}
Above result, I am trying to get a minimum rank field which is belonged to 'A' and 'B'.
We have a database with a lot of documents, which gets bigger as time goes on. Right now, query time isn't a problem since the data is only ~1 year old or so. But the bigger this gets, the longer queries will take if we query everything.
Our idea was to take every nth document, the more documents there are, you leave some data out, but you still get a good image from data over the time. However, this is hard to do in Mongo and doesn't seem to work at all, since it still traverses all documents.
Is there a way to set a fixed query time, no matter how many documents, or at least reduce it? It doesn't matter if we lose data overall, as long as we get documents from every time range.
I don't know exactly how your data looks like, but here is an example of what I mean. Let's assume this is your data stored in the database.
/* 1 */
{
"_id" : ObjectId("59e272e74d8a2fe38b86187d"),
"name" : "data1",
"date" : ISODate("2017-11-07T00:00:00.000Z"),
"number" : 15
}
/* 2 */
{
"_id" : ObjectId("59e272e74d8a2fe38b86187f"),
"name" : "data2",
"date" : ISODate("2017-11-06T00:00:00.000Z"),
"number" : 19
}
/* 3 */
{
"_id" : ObjectId("59e272e74d8a2fe38b861881"),
"name" : "data3",
"date" : ISODate("2017-10-06T00:00:00.000Z"),
"number" : 20
}
/* 4 */
{
"_id" : ObjectId("59e272e74d8a2fe38b861883"),
"name" : "data4",
"date" : ISODate("2017-10-05T00:00:00.000Z"),
"number" : 65
}
I understand you want to compare some values throughout months or even years. So you could do the following
db.getCollection('test').aggregate([
{
$match: {
// query on the fields with index
date: {$gte: ISODate("2017-10-05 00:00:00.000Z"),
$lte: ISODate("2017-11-07 00:00:00.000Z")}
}
},
{
// retrieve the month from each document
$project: {
_id: 1,
name: 1,
date: 1,
number: 1,
month: {$month: "$date"}
}
},
{
// group them by month and perform some accumulator operation
$group: {
_id: "$month",
name: {$addToSet: "$name"},
dateFrom: {$min: "$date"},
dateTo: {$max: "$date"},
number: {$sum: "$number"}
}
}
])
I would suggest you save the pre aggregated data, this way instead of searching through 30 documents per month for example you'd only need to search for 1 per month. And you'd only have to aggregate the complete data only once, if you have the pre aggregated results stored then you'd only have to run the pre aggregation for the new data that are coming in.
Is that maybe something you are looking for?
Also if you have indexes and they fields you query have indexes then this helps as well. Otherwise MongoDB has to scan every document in a collection.
I have an array of objects, and I want to query in a MongoDB collection for documents that have elements that match any objects in my array of objects.
For example:
var objects = ["52d58496e0dca1c710d9bfdd", "52d58da5e0dca1c710d9bfde", "52d91cd69188818e3964917b"];
db.scook.recipes.find({products: { $in: objects }}
However, I want to know if I can sort the results by the number of matches in MongoDB.
For example, at the top will be the "recipe" that has exactly three elements matches: ["52d58496e0dca1c710d9bfdd", "52d58da5e0dca1c710d9bfde", "52d91cd69188818e3964917b"].
The second selected has two recipes: i.e. ["52d58496e0dca1c710d9bfdd", "52d58da5e0dca1c710d9bfde"], and the third one only one: i.e. ["52d58496e0dca1c710d9bfdd"]
It would be great if you could get the number of items it had.
By using the aggregation framework, I think that you should be able to get what you need by the following MongoDB query. However, if you're using Mongoose, you'll have to convert this to a Mongoose query. I'm not certain this will work exactly as is, so you may need to play with it a little to make it right. Also, this answer hinges on whether or not you can use the $or operator inside of the $project operator and that it will return true. If that doesn't work, I think you'll need to use map-reduce to get what you need or do it server side.
db.recipes.aggregate(
// look for matches
{ $match : { products : { $or : objects }}},
// break apart documents to by the products subdocuments
{ $unwind : "$products" },
// search for matches in the sub documents and add productMatch if a match is found
{ $project : {
desiredField1 : 1,
desiredField2 : 1,
products : 1,
// this may not be a valid comparison, but should hopefully
// be true or 1 if there is a match
productMatch : { "$products" : { $or : objects }}
}},
// group the unwound documents back together by _id
{ $group : {
_id : "$_id",
products : { $push : "$products" },
// count the matched objects
numMatches : { $sum : "$productMatch" },
// increment by 1 for each product
numProducts : { $sum : 1 }
}},
// sort by descending order by numMatches
{ $sort : { numMatches : -1 }}
)