Finding embedded document without _id in MongoDB - mongodb

I am trying to find an answer on an issue that is keeping me busy for days. I would like to find and or update an embedded document in a MongDB collection (using mongoose). It is possible I know. You can do something like this:
User.findOne({_id: id}, function(err, user) {
var embeddedDoc = user.embeddedDocs.id('embeddedDocId');
});
This works indeed. However, only if you have the specific docId which I do not know (the embedded doc can be an item(x) of an array).
My question is, is this possible anyway? Or does mongodb not let us find an embedded doc without supplying an Id?
Regards, Douwe.

Yes, you can.
Use the dot notation to specify the property of the embedded document you are looking for.
Let's say you have a collection for persons with docs like this:
{
_id:123,
name:"john",
address: {
Street:"any",
zip:1234
}
}
Then you can find a person querying by an address field like this:
db.persons.find("address.zip":1234, ...)
Just consider that it won't give you only the embedded doc, but the entire document (person in this case)

Related

Put a prefix for ObjectID for MongoDB _id field

I'm trying to put a prefix before the auto generated _id, to identify from which collection came an id, but I still want to use the mongo unique id generator.
So I can know that this id model_5e1a51821c9d44000089e3e0 came from the Model collection.
Is there a solution for that without messing with random string ?
Edit
The _id need to be string castable, since I use it as id in a graphQL object. I need to differentiate ids because I use an union in my schema and resolver need to know in which table to find the data.
The _id can be generated within an application with the constructor ObjectId(). If you want to add a prefix for the generated field, you can use an embedded document as a field for the _id, like this:
_id: {
idPrefix: "Model",
_id: ObjectId("5e1bd112b7f18a490a4bafb5")
}
Other way of identifying if a document is from another collection is use a separate boolean field:
{
_id: ObjectId("5e1bd112b7f18a490a4bafb5"),
isFromModel: <boolean true or false>,
...
}
There are some options available to do this, I'm just trying to tell you the way how would I do if I need this.
Step 1: You can generate the document and it will return you ObjectId (_id) .
Step 2: Take that value and prefix it with model like this.
let _id=5e1a51821c9d44000089e3e0;let new_idValue="model_"+_id;
Step3: Now update your document by _id and push new value in place of if as
this.db.document.findByIdAndUpdate(_id,{$set:{{_id:new_idValue}})
This is what you can do. If you find some best solution than mine, let me know as well. I will highly appreciate.

Change field type for many documents in MongoDb

I'm learning MongoDb, I have many documents like this in my collection:
And I want to update my cust_id field from String to ObjectId. I can use Compass to change type but I have very many documents. I've read from Mongo document but still don't understand. Can you show me how to do this on my document for me to understand clearly.
Thank you very much!
There are a few posts here that hint at the solution.
db.students.find().forEach(function(obj) {
obj.cust_id = ObjectId(obj.cust_id);
db.students.save(obj);
});
I tested this in Atlas 4.0.6 and it worked well. I don't know, however, how well this technique will scale to a large dataset.
Just replace students with your own collection name.
I have tested this function turning a string into number and it worked well
db.students.find().forEach(obj =>{
obj.code_number= parseInt(obj.code_number);
db.students.save(obj);
});
You can also create a new collection with the results to keep the original data and check the results
db.students.find().forEach(obj=> {
obj.code_number= parseInt(obj.code_number);
db.students_new.save(obj);
});

In mongodb, how to copy a document from a collection to another collection as the value of some key?

for example,
collection Author:
{ {"name":"victor", "article":null} }
collection Article:
{ {"name":"Tomorrow", "pages":396} }
now I need to copy the document in Article to the Author, as the value of the field 'article' of 'victor'.
How? I dont find prompt method in the mongodb manual.
In Python, preferably.
Looks like you are trying to join data from different collection authors and articles.
You can achieve this using mongodb $lookup.

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.