MongoLab TTL BSON date object is not recognized - mlab

When inserting a document to the collection via the shell:
db.collection.insert({"createdAt": new Date()})
It creates a document that looks like:
{
"_id": { "$oid": xxxxxxxxxxxxxx }
"createdAt": { "$date": xxxx-xx-xxTxx:xx:xx.xxxZ }
}
The index is executed and the document is successfully deleted when it is expired (after 10 seconds for now). Though when creating a document via a restful api call, mongolab does not seem to recognize the key value pair as a BSON date type and it is not deleted. The document that is created via HTTP POST in Java is identical to the one shown above. Though when I edit the document through the mongolab website(not making any changes) and press save, it is processed as a BSON date type and then deleted as expected when the TTL is applied. I'm assuming it is because when I make the POST the body is serialized as a JSON and then the document is created as a JSON. Though if the document looks like a BSON and smells like a BSON, why doesn't mongolab treat it like a BSON until mongolab touches it by itself?

Did you solve the issue? I was having exactly the same problem. But I was calling the REST API from JavaScript.
But when I saw format of your object I noticed that the "$date" part is missing in my documents. I used format for JSON objects like this:
var doc =
{
createdAt: new Date()
}
Then I changed it to this:
var doc =
{
createdAt: {
$date: new Date()
}
}
And TTL index works now and deletes expired documents. So check the format of the documents you create over the REST API.

Related

Mongo roblox API wrapper issue

I'm using Roblox's Mongo API wrapper
https://devforum.roblox.com/t/rbx-to-mongo-a-mongodb-data-api-wrapper/1661288
However, I'm having some issues with it.
Here is my data source for mongo:
My Data Source
I'm trying to get a table of all "tokens" in a table
Lua code
It just returns an empty table.
Per the additional information in the comments, it doesn't look like you have a matching document in the database.
Currently your query is looking for a document that is similar to the following:
{
_id: 1,
name: "tokens"
}
But the document from the screenshot resembles the following instead:
{
_id: 6,
tokens: [ 1, 2, 4 ]
}
You can see a demonstration of that in this Mongo Playground.
The changes that you need to make depend on what you are trying to do. If you are trying to find a document that has a specific value in the tokens array, then you may be looking for a filter similar to { tokens: 4 }. If instead you just want to retrieve a document that has a tokens field, then you may be looking for a filter such as { tokens: { $exists: true } }.

FeathersJS Date is saved to database as string

I'm using FeathersJS.
I'm trying to patch a document changing a field with a Date object into a MongoDB database, but I get this field saved as a string and not as a Date object. I'm also using the setNow() hook, and I can see that the field specified in the setNow() hook is saved as a Date, but my field is saved as a string.
Does anybody know why this is happening?
The restriction is that MongoDB itself (unlike Mongoose) does not have a schema so all user submitted data in the body or the query will have to be converted into the type that you need to save in or query from the database in a hook. This is documented here. In your case it would be
app.service('users').hooks({
before: {
create(context) {
context.data.myDate = new Date(context.data.myDate);
return context;
}
}
});

MongoDB: verifying document was not updated

We would like to apply some auditing in our current project. For that we created a scenario but I don't see how to make point 1 and 2 atomic.
Scenario
Every document has to have a timestamp that will server
as a version. When saving a document we will:
Verify document was not changed - first compare the timestamps of the latest document docLatest
with the document we would like to store docUpdated. The timestamps must be equal.
If not, save request is refused.
If ok, go to next point.
Update the document
Create diff with the previous doc - The latest document must be our last
document. We will create a diff and store it.
I stumble upon this idea once. My idea will utilize long_polling technique. I am not going to tell you how to architect your data, but you can convert date to numeric value, and compare by it.
for 1 and 2, you can convert Date-format to number, the schema will look something like below:
var document= {
updatedAt: { type: Number, default: Date.parse(new Date()) }
}
then for every document submitted by client, just check, if the
if(latestDocument.updatedAt - prevDocument.updatedAt > 0) {
//if latest's timestamp is bigger than prev, then store it in mongodb
} else {
//if latest document is the same or even older, just ignore this document
}
for number 3. I found that, if the document has changed, do you even need to diff it? I decide to follow react/flux's method, if the document has changed just replaced the whole document.

Meteor React - Why is findOne on a single document not found in miniMongo when it does exist?

This is such a weird problem. I think it has to do with how I am querying the document. It seems like the Meteor API has changed to query documents but the docs on the website are the same.
Here is a document in the database:
meteor:PRIMARY> db.studies.findOne()
{ "_id" : ObjectId("56c12e6537014a66b16771e7"), "name" : "Study 1" }
I have subscribed to get all documents and here is what I am trying in the console to get the documents.
var study = Studies.findOne() // This works.
It returns:
_id: MongoID.ObjectID
_str: "56c12e6537014a66b16771e7"
name: 'Study 1'
I just started a new Meteor project with React. I see that my collection is returning _id: MongoId.ObjectId
This is different, I have been using Meteor for awhile with Blaze and I can't remember it returning MongoID.ObjectID instead of just the string
But now if I try and find just that one document, it does not work.
var study = Studies.findOne("56c12e6537014a66b16771e7");
or
var study = Studies.findOne({_id: "56c12e6537014a66b16771e7"});
I am positive I am queuing for the right _id field. I have double checked the ID. Why does trying to find this one document not work?
Please let me know how I can query for a document. Has something changed with Meteor? The documentation still says you can search by id string.
You need to explicitly cast object id string to an ObjectID
var study = Studies.findOne({_id: new Meteor.Collection.ObjectID("56c12e6537014a66b16771e7")});
#Jaco has the correct answer, but I wanted to answer here to clarify what the higher level issue was.
The reason why my find query was not following syntax in Meteor docs is because I inserted the document into MongoDB directly, instead of through the Meteor API.
If you insert the document directly into MongoDB, you have to query the document using the syntax #Jaco mentioned in his answer.
Similar question: Meteor - Find a document from collection via Mongo ObjectId
So instead of changing my query code, I just deleted the document I inserted directly into MongoDB, and inserted a documented using the console in the browser.
Now I can query the document like normal.
So the root of the issue is that if you insert the document directly into MongoDB, you don't get the same type of document as you would if you insert the document using the Meteor API.

Find the collection name from document._id in meteor (mongodb)

From the looks of the syntax for handling mongodb related things in meteor it seems that you always need to know the collection's name to update, insert, remove or anything to the document.
What I am wondering is if it's possible to get the collection's name from the _id field of a document in meteor.
Meaning if you have a document with the _id equal to TNTco3bHzoSFMXKJT. Now knowing the _id of the document you want to find which collection the document is located in. Is this possible through meteor's implementation of mongodb or vanilla mongodb?
As taken from the official docs:
idGeneration String
The method of generating the _id fields of new documents in this collection. Possible values:
'STRING': random strings
'MONGO': random Meteor.Collection.ObjectID values
The default id generation technique is 'STRING'.
Your best option would be to insert records within a pseudo transaction where the second step is to take the id and collection name to feed it into a reference collection. Then, you can do your lookups from that.
It would be pretty costly, though to construct your find's but might be a pattern worthwhile exploring if you are building an app where your users will be creating arbitrary data patterns.
You could accomplish this by doing a findOne on all of the collections:
var collectionById = function(id) {
return _.find(_.keys(this), function(name) {
if (this[name] instanceof Meteor.Collection) {
if (this[name].findOne(id)) {
return true;
}
}
});
};
I tested this on both the client and the server and it seemed to work when run in the global context.