Mongo Shell script to modify DateTime to valueOf() in milliseconds, Epoch - javascript

Because GraphQL doesn't use the DateTime scalar, I have decided to convert all the fields in my MongoDB database collections that are of the type, DateTime, into Integer, representing DateTime as milliseconds. I have about 8,000+ documents that need to be modified and created a script to do the work.
The script was supposed to create a new field "publishedID", Integer scalar, to correspond with the "published" field. When I loaded my script, all the documents were over written, leaving only the DateTime field - although, as I intended, in milliseconds - but all the other fields, such as, "title", "image", "body", "subtitle", including other DateTime types like, "modified" and "created", etc. were deleted.
Below is the script I ran:
db.Post.find().forEach(function(myDoc) {
let currentDate = new Date(myDoc.published);
print(currentDate);
db.Post.update(
{ published: currentDate },
{ publishedID: currentDate.valueOf() }
);
});
I had hoped the ISO DateTimes, previously set for the "published" field would just have been converted to milliseconds, I got that. But I did not want everything else in the document deleted.

Here, you are missing the $set operator in the update query which is the root cause of all fields deletion in the documents
db.Post.find().forEach(function(myDoc) {
let currentDate = new Date(myDoc.published);
print(currentDate);
db.Post.update(
{ published: currentDate },
{ $set: {publishedID: currentDate.valueOf()} } // $set: {} added
);
});
$set operator updates the given fields but here we have added one field only which will replace the existing fields in the matched collections.

Related

Mongodb deleteMany or dump with specified date

Maybe this subject often question to ask, but I not find what I want it.
I have a collection with keys and values like this:
{
_id: ObjectId("6142f3a47245125aef7ffcc0"),
addTime: '2021-09-16 14:35:00',
editTime: '2021-09-16 14:35:00'
}
I want to dump before August 2021. What syntax do I have to use?
I trying in roboT and mongo shell, before dump I try find first.
db.collections.find({addTime:{$lte:new Date("2021-09-01")}})
and the result is
Fetched 0 record(s) in 3714ms
You can make use of the $expr operator to temporarily convert the string to a date-time value and then perform your query.
db.collection.find({
"$expr": {
"$lte": [
{
"$dateFromString": {
"dateString": "$addTime",
"format": "%Y-%m-%d %H:%M:%S", // <- Your date time format in string
"onNull": new Date("9999-09-01"), // <- Default calue if query key doesnt exist (Dont modify this value, unless required)
}
},
new Date("2021-09-01"), // <- Your datetime query value (can also be `ISODate` format)
],
}
})
Mongo Playground Sample Execution

Compare date and time in Mongo

I'm writing a mongo query to show records based on the current time. However, the query returns 0 records when I try to query against date and time. Below is the query:
let now = momenttz.tz(moment(),tz).toDate();
tmpl.listSelectorFilter('scheduledVisits', {
$gte: now,
$lte: moment.utc(today, 'MM/DD/YYYY').endOf('week').toDate()
});
Note: If I set the time to zero hours, it works.
How do I change this query in order to make it work? Any help is appreciated.
Does the data you're querying against have timestamps or a dateTime object to compare? Essentially you aren't comparing the records to any time, so there is no way for mongo to know what to filter by.
I would suggest you do something like a find instead and compare to dates within the record with the appropriate date field:
example:
db.collection.find({
{ $and: [ { data.date: { $gte: now } }, { data.date: { $lte: endOfWeek } } ] }
})
also keep in mind that in mongo land you can't use functions like you would do with moment, hence why I put "endOfWeek" which would be a variable you set similar to now:
let now = momenttz.tz(moment(),tz).toDate();
let endOfWeek = moment.utc(today, 'MM/DD/YYYY').endOf('week').toDate()

How do I query MongoDB for 2 ranges and text search?

I have event objects in MonogDB that look like this:
{
"start": 2010-09-04T16:54:11.216Z,
"title":"Short descriptive title",
"description":"Full description",
"score":56
}
And I need to get a query across three parameters:
Time window (event start is between two dates)
Score threshold (score is > x)
Full-text search of title and description
What's the right way to approach this efficiently? I think the first two are done with an aggregation but I'm not sure how text search would factor in.
Assuming your start field is of type date (which it should be) and not a string, here are the basic components that you'd want to play with. In fact, given the ISO 8601 structure of a MongoDB date a string based comparison would work just as well.
// create your text index
db.collection.ensureIndex({
description: "text",
title: "text"
})
// optionally create an index on your other fields
db.collection.ensureIndex({
start: 1,
score: 1
})
x = 50
lowerDate = ISODate("2010-09-04T16:54:11.216Z") // or just the string part for string fields
upperDate = ISODate("2010-09-04T16:54:11.216Z")
// simple find to retrieve your result set
db.collection.find({
start: {
$gte: lowerDate, // depending on your exact scenario, you'd need to use $gt
$lte: upperDate // depending on your exact scenario, you'd need to use $lt
},
score: { $gt: x }, // depending on your exact scenario, you'd need to use $gte
$text: { // here comes the text search
$search: "descriptive"
}
})
There is an important topic with respect to performance/indexing that needs to be understood, though, which is very well documented here: Combine full text with other index
This is why I initially wrote "components of what you'd want to play with". So depending on the rest of your application you may want to create different indexes.

How to create a query on a Date field in MongoDB using mongoose?

I am trying to query a collection in Mongo database, to get all record with Time field in a date range. Time is defined as Date in database.
My environment: Node.js, Express, Jade, javascript.
This is the javascript code:
var query = {};
var timeQuery = {};
timeQuery["$lt"] = new Date().toISOString();
query["Time"] = timeQuery;
console.log(query);
db.model('testruns').find(query).exec(function (err, testruns) {
console.log(testruns.length);
// doing something
});
the result printed to console:
{ Time: { '$lt': '2014-10-30T15:04:39.256Z' } }
0
The query returns 0 results (there should be more)
By the way... Running date queries from RoboMongo returns results, just the wrong ones. for example:
db.testruns.find({Time : {"$gte" : new Date("2014-10-30T15:13:37.199Z")}})
returns all records.
What I tried:
This one, that one, another one, mongoose documentation of course, and many more results from google.
Most of them give the same answer, none of them works for me. HELP!
as far I see you are not including the field to reference in the query, can you try this:
I assume your field name is 'time'
var date = new Date(); //or the date you want to compare
db.model('testruns').find({"Time":{"$lt":date}}).exec(function (err, testruns) {
console.log(testruns.length);
// doing something
});
The problem was related to a schema definition, not directly to this code. The code of the query was correct. a schema definition had this field(Time) as String, which caused MongoDB to try and find a string in a date field...

A filtered and sorted view in CouchDB?

I have some items in CouchDB with a timestamp field and a group field. I use this view function to get a list of all items where group == "foo":
{
"map" : "function(doc) { emit(doc.group, doc); }"
}
http://localhost:5984/my_database/_temp_view?key="foo"
Now I'd like to make the output sorted by the timestamp field. How do I do that? Basically, I want the equivalent of this SQL query:
SELECT * FROM SomeTable WHERE group=? ORDER BY timestamp
Emit the timestamp as a second column:
function(doc) { emit([doc.group,doc.timestamp]); }
Then, query with the following parameters:
view?startkey=["foo"]&endkey=["foo",""]
I am assuming that your timestamps are numbers, not strings. Read this to understand how the numeric timestamps will be sorted in-between ["foo"] and ["foo",""].
Also, don't emit doc as the value, it uses a lot of storage. If you really need the document, use include_docs=true in your query.

Categories