I have a lastModified attribute in my games collection. At the moment I have to manually update the lastModified attribute on every change (current timestamp).
Is it possible to update this attribute automatically when other attributes of the document will be changed?
I use Meteor 1.0.
EDIT:
Sample document:
{ "controllerId" : "ACycCfrQuTtuMwjuJ", "body" : "ABC", "userId" : "5iE4P8HPoRCSHe6k8", "lastModified" : ISODate("2015-01-06T15:48:49.346Z"), "_id" : "CQbL49FP9rZkSF7yh" }
When changing attribute body it should be like this:
{ "controllerId" : "ACycCfrQuTtuMwjuJ", "body" : "XYZ", "userId" : "5iE4P8HPoRCSHe6k8", "lastModified" : ISODate("2015-01-06T19:41:19.888Z"), "_id" : "CQbL49FP9rZkSF7yh" }
lastModified should automatically be updated when one of the other attributes changes.
As explained here, you can abuse the deny mechanism to do this for you:
Games.deny({update: function(userId, doc) {
doc.lastModified = new Date();
return false;
}})
Alternatively you can use collection hooks. Your exact use case is the example for before.update.
Related
How can I merge the documents together where the user is the same?
What I find difficult to do is to automatically add the values from the "field" column as columns and the data from the "data" field as values for the newly created columns.
Like merging these two because they have the same user id and have the columns "Date of birth":"1989-01-12" and "Job":"Teacher".
I know it's a lot to ask, but could someone guide me to how to achieve this?
{
"_id" : ObjectId("5d6b00b960016c4c441d9a16"),
"user" : 1000,
"field" : "Date of birth",
"data" : "1989-01-12",
"timestamp" : "2017-08-27 11:00:59"
}
{
"_id" : ObjectId("5d6b00b960016c4c441d9a17"),
"user" : 1000,
"field" : "Job",
"data" : "Teacher",
"timestamp" : "2017-08-27 10:59:19"
}
Into
{
"_id" : ObjectId("5d6b00b960016c4c441d9a16"),
"user" : 1000,
"Date of birth" : "1989-01-12",
"Job" : "Teacher",
"timestamp" : "2017-08-27 11:00:59"
}
To merge documents, you can iterate them to create a new document.
If you want to remove the old references to the given user, you have to delete them before inserting your new document.
You can go like this using the javascript interface of MongoDB:
// Get the docs
docs = db.find({user:1000})
// Init common values of the new doc
new_doc = db.findOne({user:1000})
// Remove the unused field in the new object
delete new_doc.field
delete new_doc.data
for (i=0; i<docs.size(); i++){
doc = docs[i]
new_doc[doc["field"]] = new_doc["data"]
if (Date(doc["timestamp"]) > Date(new_doc["timestamp"])) {
new_doc["timestamp"] = doc["timestamp"]
}
}
// remove all references to the user if you need to
db.remove({user:1000}, {multi:true})
// insert the merged document
db.insert(new_doc)
I tried to create category hierarchy.So,I refer this link (https://docs.mongodb.com/ecosystem/use-cases/category-hierarchy/) link given number example how to create category hierarchy .but I have a doubt I this example is used slug field.why to use slug I could not understand can you please give solution.
Example Document
{ "_id" : ObjectId("4f5ec858eb03303a11000002"),
"name" : "Modal Jazz",
"parent" : ObjectId("4f5ec858eb03303a11000001"),
"slug" : "modal-jazz",
"ancestors" : [
{ "_id" : ObjectId("4f5ec858eb03303a11000001"),
"slug" : "bop",
"name" : "Bop" },
{ "_id" : ObjectId("4f5ec858eb03303a11000000"),
"slug" : "ragtime",
"name" : "Ragtime" } ]
}
what is slug ?
Which purpose using in document ?
why to use slug field ?
Slug field is URL shortcut to get document or sub/document is simple way.
Slug is used in document to make easy get document from URL
For example, typing http://**host**/modal-jazz you should get document that has "modal-jazz" as 'slug'.
I hope i helped you a bit.
I have a collection called answers which has dozens of documents in it.
I would like to add a new property called archive at the end of each document in this collection.
Final state of the collection record should be like shown below where archive property is added to each document.
{
"_id" : ObjectId("5b30b90f40d08d8871c2d2fd"),
"createdAt" : ISODate("2018-06-25T09:42:39.870Z"),
"updatedAt" : ISODate("2018-09-17T08:30:04.300Z"),
"status" : "overdue",
"archive" : ""
}
you should try
db.answers.updateMany({},{$set:{archive:"1"}})
Additional references are Here
I have MongoDB Collection where some documents have arrays of objects. One of the fields of this objects is timestamp.
The problem is that historically some of timestamp values are Strings (e.g. '2018-02-25T13:33:56.675000') or Date and some of them are Double (e.g. 1528108521726.26).
I have to convert all of them to Double.
I've built the query to get all the documents with the problematic type:
db.getCollection('Cases').find({sent_messages: {$elemMatch:{timestamp: {$type:[2, 9]}}}})
And I also know how to convert Date-string to double using JS:
new Date("2018-02-18T06:39:20.797Z").getTime()
> 1518935960797
But I can't build the proper query to perform the update.
Here is an example of such a document:
{
"_id" : ObjectId("6c88f656532aab00050dc023"),
"created_at" : ISODate("2018-05-18T03:43:18.986Z"),
"updated_at" : ISODate("2018-05-18T06:39:20.798Z"),
"sent_messages" : [
{
"timestamp" : ISODate("2018-02-18T06:39:20.797Z"),
"text" : "Hey",
"sender" : "me"
}
],
"status" : 1
}
After the update it should be:
{
"_id" : ObjectId("6c88f656532aab00050dc023"),
"created_at" : ISODate("2018-05-18T03:43:18.986Z"),
"updated_at" : ISODate("2018-05-18T06:39:20.798Z"),
"sent_messages" : [
{
"timestamp" : 1518935960797.00,
"text" : "Hey",
"sender" : "me"
}
],
"status" : 1
}
As per your question, you are trying to fetch the record first.
db.getCollection('Cases').find({sent_messages: {$elemMatch:{timestamp: {$type:[2, 9]}}}})
Then convert date in JS:
new Date("2018-02-18T06:39:20.797Z").getTime()
And then this is an update query:
db.getCollection('Cases').updateOne({_id:ObjectId("6c88f656532aab00050dc023")}, { $set: { "sent_messages.$.timestamp" : "218392712937.0" }})
And if you want to update all records then you should write some forEach mechanism. I think you have already this implemented.
Hope this may help you.
Finally I just do it with JS code that can be run in mongo console:
db.getCollection('Cases').find({sent_messages: {$elemMatch:{timestamp: {$type:[2, 9]}}}}).forEach(function(doc) {
print('=================');
print(JSON.stringify(doc));
doc.sent_messages.forEach(function(msg){
var dbl = new Date(msg.timestamp).getTime();
print(dbl);
msg.timestamp = dbl;
});
print(JSON.stringify(doc))
db.Cases.save(doc);
} )
Thanks all for your help!
I'm a newbie with MongoDB, and am trying to store user activity performed on a site. My data is currently structured as:
{ "_id" : ObjectId("4decfb0fc7c6ff7ff77d615e"),
"activity" : [
{
"action" : "added",
"item_name" : "iPhone",
"item_id" : 6140,
},
{
"action" : "added",
"item_name" : "iPad",
"item_id" : 7220,
}
],
"name" : "Smith,
"user_id" : 2
}
If I want to retrieve, for example, all the activity concerning item_id 7220, I would use a query like:
db.find( { "activity.item_id" : 7220 } );
However, this seems to return the entire document, including the record for item 6140.
Can anyone suggest how this might be done correctly? I'm not sure if it's a problem with my query, or with the structure of the data itself.
Many thanks.
You have to wait the following dev: https://jira.mongodb.org/browse/SERVER-828
You can use $slice only if you know insertion order and position of your element.
Standard queries on MongoDb always return all document.
(question also available here: MongoDB query to return only embedded document)