I still can't seem to do what I want to do. My Data Base:
{lastSeen: { $date: {$numberLong: 1614618000000 }}}
I want substract days to value and selects the documents where the value of the field is greater than or equal. I test this:
{"lastSeen": { "$gte": {"$date": { "$subtract": [ "$date", 1616000000000 ] }}}}
but the response is 'no result to show' on Gamesparks.
When i test with this query:
{"lastSeen": { "$gte": {"$date": "2021-03-13T00:00:00.000Z"}}}
i have responses.
An idea ? Thank you.
Related
i am working on a problem where in my database there supposed to be multiple entries from day to day.
each entry includes a timestamp. the problem is im supposed to find how many days in each month a data has been entered.
ex: if a user sends a message every 2 days in may. my answer would be: "the user used the message function for 15 days in may".
now if the user sends 5 messages every 2 days in may. the answer would be still 15. im only counting the days the user has been using the app.
using this query:
model.find({
date: {
$gte: new Date(startOfMonth),
$lt: new Date(endOfMonth)
}
})
i was able to find all data entries on a specific month.
the data may look like something like this:
Date: dd/mm/yy Message:
1/5/2022 "Hello"
1/5/2022 "World"
1/5/2022 "!"
5/5/2022 "Hello World!"
8/5/2022 "Hello World!"
the desired answer would be 3 unique days in may.
How do i achieve this using mongodb? the simplest answer that come to mind is to use additional queries to group by unique days, but i have no idea how to do that using mongo provided i need to access the date.
This might solves your problem. it will return distinct messages.
Model.aggregate(
[
{ "$match": {
"date": {
"$gte": new Date(startOfMonth), "$lt": new Date(endOfMonth)
}
}},
{ "$group": {
"_id": {
"year": { "$year": "$date" },
"month": { "$month": "$date" },
"day": { "$dayOfMonth": "$date" }
}
"count": { "$sum": 1 }
}}
],
function(err,result) {
// do something with result
}
);
You can use distinct
db.collection.distinct({date:{$gte:new Date(startOfMonth),$lt:new Date(endOfMonth)}}).length
if you are directly storing the date of it.
Note : This may not work if you're storing complete timestamp instead of date.
I'm looking to write a query to aggregate the quantity based on dates.
I have documents that look like this:
{
"_id" : 1234,
"itemNumber" : "item 1",
"date" : ISODate("2021-10-26T21:00:00Z"),
"quantity" : 1,
"__v" : 0
}
And a query like this:
//monogoose
myCollection.aggregate().group({
_id: '$itemNumber',
ninetyDays: {
$sum: {
$and: {
$gte: ["date", dayjs().subtract(90, 'd').toDate()],
$lt: ["date", dayjs().toDate()]
}
}
}
})
In the query above ninetyDays is always 0.
I'm basically looking to get the sum of the quantity given a date range.
Help is much appreciated.
Thank you
You can use $cond to sum 1 or 0 if your condition is match.
Assuming your date expression is correct this should works, but don't forger $ in date.
db.collection.aggregate([
{
"$group": {
"_id": "$itemNumber",
"ninetyDays": {
"$sum": {
"$cond": {
"if": {
"$and": [
$gte: ["$date", dayjs().subtract(90, 'd').toDate()],
$lt: ["$date", dayjs().toDate()]
]
},
"then": 1,
"else": 0
}
}
}
}
}
])
Example here where I've used mongo $$NOW but if your date works is easier to use your code.
My mongoDB collection looks like this:
[
{
"id": "myid",
"field": {
"total": 1,
"subfield": [
{
"time": "2020-08-06T08:33:57.977+0530"
},
{
"time": "2020-05-08T04:13:27.977+0530"
}
]
}
},
{
"id": "myid2",
"field": {
"total": 1,
"subfield": [
{
"time": "2020-07-31T10:15:50.184+0530"
}
]
}
}
]
I need to update all the documents and convert date string in the field time available in the subfieldarray to mongoDB ISO date format.
I have thousands of documents and hundreds of objects in subfield array
I'm aware of the aggregate function $todate and $convert.
But I don't want to use aggregation because,
To use $todate or $convert, I need to unwind the field.subfield array which is again an expensive operation.
I want to update my document and save it with the date format.
My MongoDB server version: 4.0.3
I tried the following but it doesn't seem to work and also doesn't return any errors.
db.collection.find().forEach(function(doc) {
doc.field.subfield.time=new ISODate(doc.field.subfield.time);
db.collection.save(doc);
})
You missed a loop for subfield, because its an array,
db.collection.find().forEach(function(doc) {
doc.field.subfield.forEach(function(r) {
r.time = new ISODate(r.time);
})
db.collection.save(doc);
})
If this is for one time then time does not matter, i think both will take same time if you do with aggregation or forEach.
If you are planing to update MongoDb version then form 4.2,
a option you can update with updateMany() using update with aggregation pipeline,
db.collection.updateMany({},
[{
$set: {
"field.subfield": {
$map: {
input: "$field.subfield",
as: "r",
in: {
$mergeObjects: [
"$$r",
{ time: { $toDate: "$$r.time" } }
]
}
}
}
}
}]
)
What's the best way to go about getting the highest "score" for each "date" and storing them into an array. Let's the say there are over 50 scores for any particular date.
The database looks like this
{
"_id" : ObjectId("5c06b91b583248493294"),
"classid" : "00010109e2",
"score" : 720,
"height" : 1440,
"time" : "2018-11-27T18:05:13.297621823Z",
"__v" : 0
}
And what I'm trying to do is get the highest score for each date, from a date-range of around 2 weeks and store one highest score for each date in a simple array.
I've tried loads of things, including recursion to no avail.
Can anyone shed any light on this, or point me in the right direction?
You should look into mongodb aggregation and especially $group operator, it usually used to perform such kind of operations.
In this case your code will look like that:
Scores.aggregate([
{
$match: {
time: {
$gte: startOfSomePeriod,
$lte: endOfSomePeriod
}
}
},
{
$group: {
_id: {
year: { $year: "$time" },
month: { $month: "$time" },
day: { $dayOfMonth: "$time" }
},
score: { $max: "$score" }
}
}
]);
P.S. You can use mongooses default createdAt timestamp by simply adding an option to your schema definition.
I am wondering if there is a way to get a MongoDB document age in hours? Here's what I have so far, but obviously I'm using a date object, it is not calculating the hours, and it's not giving the age, just the date it was created, so it is not giving the desired result. In fact, the $divide pipeline does not even allow for date objects. Any help is appreciated. Just as an FYI, the $views variable is a NumberInt32 type and the $created_at variable is a timestamp, like: 2014-05-20T00:01:08.629Z.
db.projects.aggregate({
$project: {
"result": {
$divide: ['$views', '$created_at']
}
}
)
If you're wondering, this code is to help sort popular posts, but of course, it's only part of it. Thanks for any help!
Presuming that $views and $created_at are fields in your document containing a number of views and the created timestamp as follows:
{
"_id" : ObjectId("537abe5e8da9877dbb0ef604"),
"views" : 5,
"created_at" : ISODate("2014-05-20T00:00:00Z")
}
Then just a little date math getting the difference from the current time should do:
db.projects.aggregate([
{ "$project": {
"score": { "$divide": [
{ "$divide": [
{ "$subtract": [
new Date(),
"$created_at"
]},
100*60*60
]},
"$views"
]},
"created_at": 1,
"views": 1
}}
])
So you are basically getting the difference in hours from the current time as a date object and the created_at value. Dividing that by a standard number for hours in a day, then dividing by your views in order to get your "score" result for sorting.
When you do math operations with two date objects then the result is returned as a number. So further operations with just numbers will work from then on.