MongoDB equivalent to NOW() + INTERVAL - mysql

I'm currently working on converting our PHP backend from MySQL to MongoDB.
We are often using something like this in MySQL:
UPDATE table_1 SET completion_time = NOW() + INTERVAL 90 MINUTE WHERE id = 1;
How would I do this in MongoDB? Do I need to use 2 queries? First query to set completion_time with $currentDate and the 2nd query to increment it? I've read that $inc doesn't work on Dates in MongoDB, tho ...

You could try creating a date variable that holds the current date + 90 minutes later which you can then use to set the completion_time field with in your update:
var ninetyMinutesLater = new Date();
ninetyMinutesLater.setMinutes(ninetyMinutesLater.getMinutes() + 90);
db.table_1.update(
{ "_id": 1 },
{
"$set": {
"completion_time": ninetyMinutesLater
}
}
);

I see you have have tagged this with mongodb-php so I assume you are using PHP. MongoDB does have a $currentDate operator but currently there is no way to actually set an offset to that date.
For example I tried #diwakar's answer on 3.0:
> db.table_1.update({"id":1 },{completion_time: { $add: [ "$currentDate", 90 ] }})
2015-03-23T11:22:05.497+0000 E QUERY Error: field names cannot start with $ [$add]
at Error (<anonymous>)
at DBCollection._validateForStorage (src/mongo/shell/collection.js:160:19)
at DBCollection._validateForStorage (src/mongo/shell/collection.js:164:18)
at DBCollection._validateUpdateDoc (src/mongo/shell/collection.js:387:14)
at Object.findOperations.updateOne (src/mongo/shell/bulk_api.js:675:20)
at DBCollection.update (src/mongo/shell/collection.js:454:22)
at (shell):1:12 at src/mongo/shell/collection.js:160
So currently this needs to be done client side like so:
$mongo->collection->insert(['completion_time' => new MongoDate(time() + (60*90))])
It seems that is the only way.

Starting with MongoDB v5.0+, you can use $dateAdd with $$NOW.
db.collection.update({
_id: 1
},
[
{
$set: {
completion_time: {
"$dateAdd": {
"startDate": "$$NOW",
"unit": "minute",
"amount": 90
}
}
}
}
])
Here is the Mongo Playground for your reference.

use
db.collection.UpdateOne({ _id:id},{
$set:{
"completion_time": $add:[ $currentDate , (60*90)]
}
})

Please try this definitely work,
db.table_1.update({"id":1 },{completion_time: { $add: [ "$date", 90 ] }})

Related

Convert array of hash by logstash to simple hash

I am trying to parse by logstash this:
"attributes": [
{
"value": "ValueA",
"name": "NameA"
},
{
"value": "ValueB",
"name": "NameB"
},
{
"value": "ValueC",
"name": "NameC"
}
],
To this:
"attributes": {
"NameA": "ValueA",
"NameB": "ValueB",
"NameC": "ValueC"
}
Any recommendations?
I don't want to split this list to more records...
I have found th solution. For anyone dealing with a similar problem, here is the solution and a short story...
In the beginning, I tried this:
ruby {
code => '
xx = event.get("[path][to][data_source]")
event.set(['_my_destination'], Hash[xx.collect { |p| [p[:name], p[:value]] }])
'
But it returned an error because of the set method allowing a string only.
So I tried to do it this way:
ruby {
code => '
event.get("[path][to][data_source]").each do |item|
k = item[:name]
event.set("[_my_destination][#{k}]", item[:value])
end
'
}
I spent a lot of time debugging it because it works everywhere except in logstash :-D. After some grumbling, I finally fixed it. The solution with commentary is as follows.
ruby {
code => '
i = 0 # need index to address hash in array
event.get("[json_msg][mail][headers]").each do |item|
# need to use event.get function to get value
k = event.get("[json_msg][mail][headers][#{i}][name]")
v = event.get("[json_msg][mail][headers][#{i}][value]")
# now it is simple
event.set("[json_msg][headers][#{k}]", v)
i += 1
end
'
}
I think you should be able to do it with a custom Ruby script - see the ruby filter. You'll use the Event API to manipulate the event.
Maybe the aggregate filter could be also used but the Ruby script with one for loop seems more straightforward to me.

How will we ignore duplicates while insert json data into mongoDB based on multiple condition

[
{
"RollNo":1,
"name":"John",
"age":20,
"Hobby":"Music",
"Date":"9/05/2018"
"sal":5000
},
{
"RollNo":2,
"name":"Ravi",
"age":25,
"Hobby":"TV",
"Date":"9/05/2018"
"sal":5000
},
{
"RollNo":3,
"name":"Devi",
"age":30,
"Hobby":"cooking",
"Date":"9/04/2018"
"sal":5000
}
]
Above is the JSON file i need to insert into a MongoDB. Similar JSON data is already in my mongoDB collection named 'Tests'.I have to ignore the records which is already
in the mongoDB based on a certain condition.
[RollNo in mongoDB == RollNo in the json need to insert && Hobby in mongoDB ==Hobby in the json need to insert && Date in mongoDB == Date in the json need to insert].
If this condition matches, i need to igore the insertion,else need to insert the data into DB .
I am using nodejs. Anyone please help me to do it.
If you are using mongoose then use upsert.
db.people.update(
{ RollNo: 1 },
{
"RollNo":1,
"name":"John",
"age":20,
"Hobby":"Music",
"Date":"9/05/2018"
"sal":5000
},
{ upsert: true }
)
But to avoid inserting the same document more than once, only use upsert: true if the query field is uniquely indexed.
The easiest and safest way to do this is by using a compound index.
You can create a compound index like this:
db.people.createIndex( { "RollNo": 1, "Hobby": 1, "Date" : 1 }, { unique: true } )
Then the duplicated inserts will produce an error which you need to process in your code.

How to get id from text

I have value text:
{
"4384": {
"idRoomSv": 4384,
"NumRoom": 2,
"RoomId": 269
}
}
I want to get RoomId. It is return :269.
Can you help me? Thank very much!
If you have a recent version of MariaDB or MySQL, you can use the JSON_EXTRACT function.
Edit: try on your sql client the code below
SET #json = '{
"4384": {
"idRoomSv": 4384,
"NumRoom": 2,
"RoomId": 269
}
}';
SELECT JSON_EXTRACT(#json, '$.*.RoomId');
And the result is :
JSON_EXTRACT(#json, '$.*.RoomId')
1 [269]
The JSON_EXTRACT function accepts a JSON document for the firtst parameter. The second parameter is a JSONPath expression :
$ : is the root element
* : wildcard = all elements regardless their names
RoomId : value of that field

N1QL convert timezone into date,Couchbase

I want to convert 2015-10-29T16:15:11.000Z in to 2015-10-29 Date in N1QL query.
How can I do it ?
There are a couple of options here. The simplest way works if you can tolerate an ISO 8601 formatted time and uses the DATE_TRUNC_STR(expression, part) Date function:
SELECT DATE_TRUNC_STR(date_time, "day") AS new_date FROM bucket
The result for such a query (using 2015-10-29T16:15:11.000Z as date_time) is:
{
"results": [
{
"new_date": "2015-10-29T00:00:00Z"
}
]
}
Alternatively, you can parse out the individual parts using the DATE_PART_STR(expression, part) function with the TOSTRING(expression) function with String concatenation (||):
SELECT TOSTRING(DATE_PART_STR(date_time, "year")) || "-" || TOSTRING(DATE_PART_STR(date_time, "month")) || "-" || TOSTRING(DATE_PART_STR(date_time, "day")) AS new_date FROM bucket
The result:
{
"results": [
{
"new_date": "2015-10-29"
}
]
}
Reference:
https://docs.couchbase.com/server/current/n1ql/n1ql-language-reference/datefun.html

How to format datatime for json

I''m using EF to query the database using anonymous type.
here the code I use for EF
public JsonResult OverdueEventsCustom()
{
var eventCustomOverdue = _eventCustomRepository.FindOverdueEventsCustom();
return Json(eventCustomOverdue, JsonRequestBehavior.AllowGet);
}
public IQueryable<dynamic> FindOverdueEventsCustom()
{
DateTime dateTimeNow = DateTime.UtcNow;
DateTime dateTomorrow = dateTimeNow.Date.AddDays(1);
return db.EventCustoms.Where(x => x.DateTimeStart < dateTomorrow)
.Select(y => new { y.EventId, y.EventTitle, y.DateTimeStart});
}
Inspecting using the debugger I see the properties is in this format
Date = {16/08/2012 00:00:00}
The resultfor the JSON is
[{
"EventId": 1,
"EventTitle": "Homework Math",
"DateTimeStart": "\/Date(1345108269310)\/"
}, {
"EventId": 4,
"EventTitle": "Homework help with Annie",
"DateTimeStart": "\/Date(1345108269310)\/"
}, {
"EventId": 6,
"EventTitle": "Physic laboratory",
"DateTimeStart": "\/Date(1345108269310)\/"
}]
I need the the json in this format
"DateTimeStart": "(16/08/2012)"
Any idea what i'm doing wrong here? thanks for your help
Related articles
http://www.hanselman.com/blog/OnTheNightmareThatIsJSONDatesPlusJSONNETAndASPNETWebAPI.aspx
How do I format a Microsoft JSON date?
"\/Date(1345108269310)\/" is the correct way to pass a Date to javascript. The way I see it, you have two options here:
If you do not explicitly need the value as a date, you could just pass a string to the JSON variable, containing the pretty-printed date.
Something along the lines of:
DateTimeStart: String.Format("{0: dd-MM-yyyy}", myDate)
If you will still need to use the variable a a date in javascript (for calculations for example), the most consice and readably way would be to create a javascript function that converts said date into the pretty-printed string you want (I don't know if such a function already exists. It isn't too hard to create though:
function prettyDate(date) {
return date.getDate() + "-" + date.getMonth() + "-" + date.getFullYear();
}
I would suggest passing it along as a string from you code behind, as it is more readable. But that only works if you do not need to use the date except for displaying.