This is probably an obvious question, but I can't find a clear answer to it.
In MongoDB, suppose I embed document food into document super_market. When I make a change to the food document, will the embedded document in super_market automatically get updated?
Your question denotes a structure like this:
example Super_market:
{ "super_market_name": "SuperMart",
"address": "1 Main Street",
"food": { "food_name":"apple" }
}
It sounds like you're asking about a food document that is separate from the super_market and linked to it.
If you embed the 'food' document as above, the embedded document is the one that you would be altering. It doesn't exist in a separate location that you would modify. If you update super_market.food, the embedded document is the one (and only) that will be affected.
Related
I have two "documents" that I inserted into my MongoDB database.
questionsList.insert({question: "When was the War of 1812", answer: "1812", answers: ["1811", "1812", "1813", "1814"]})
questionsList.insert({question: "What year did the US land on the moon?", answer: "1969", answers: ["1969", "1970", "1971", "1972"]})
I simply want to access the answer value from the second document. I have been reading the documentation and it doesn't seem to work. I can retrieve the answer value from the first document without issue: var str = questionsList.findOne({}, {question: 1}).answer; I presume that since I am using findOne I can't find any other matches. The problem is that I can't seem to pull up the second document and its corresponding answer. I have tried many different ways:
questionList.find({}, {answer: 1})
questionList.find({answer: 1})
questionList.find({}).answer
My ultimate goal is to compare this answer with one of the click one answers from choices What am I missing?
If I understood your scenario correctly, you are trying to retrieve a document based on the document index (Which is not the right thing to do, since MongoDB does not store documents in specific order).
The reason why findOne works is, because it just returns the first document in your collection.
What I believe you should do instead is retrieve the answer based on the question. Something like:
db.questionsList.find({question:"What year did the US land on the moon?"},{answer:1})
Update:
In the case of meteor.js
questionsList.find({question:"What year did the US land on the moon?"}).fetch()[0].answer
The reason whey we need to give [0] is fetch() returns an array of objects. (Since there can be multiple documents with same key)
The final step is:
questionsList.find({"question": "You are human"}, {"answer": 1}).fetch()[0].answer
We are treating it as any other object (i.e. the first within a list of objects and using dot-notation)
My 'Programs' collection would look like this (as an array);
[{ FullName: "Jane Doe", CampYear: "mays15",...}, { FullName "Jane Doe", CampYear: "mays16",...},...]
Some people in the collection are newbies and have just one document in the collection. Others have multiple documents and are returnees. We'd like the ability to mark or flag somehow the newbies. Somehow iterate through the collection and single out those who just have one document in there. The trouble is if I have a list of, say, 150 names, for each name I'd have to have a separate find operation on the collection, which is too intensive.
I tried using aggregation via the meteorhacks:aggregate but couldn't get it to work. After loading the package, my IDE wouldn't recognize the .aggregate method at all, even on the server.
Underscore might be a worthwhile way of doing it, but I couldn't find a method that might be of assistance.
Any ideas how we could do this?
Based on your comment, I'd probably denormalize your data. I'd have a new collection called CampAttendance or something like that. Then you'd have the structure:
{
"name": "The camper's name",
"years": ["mays2015", ...]
}
You can then use upsert to either insert a new record or $push another camp year onto the years array as you're importing data.
To get the camper names who are 'newbies' then, you do:
CampAttendance.find({ years: { $size: 1 } });
I'am looking for a good solution on MongoDB for this problem:
There are some Category's and every Category has X items.
But some items can be in in "many" Category's!
I was looking for something like a symbolic link on Unix systems but I could't not find it.
What i thought is a good idea is:
"Category1/item1" is the Object and "category2/item44232" is only a reference to "item1" so when i change "item1" it also changes "item44232".
I looked into the MongoDB Data models documentation but there is no real solution for this.
Thank you for your response !
In RDBMSs, you use a join table to represent one-to-many relationships; in MongoDB, you use array keys. For example each product contains an array of category IDs, and both products and categories get their own collections. If you have two simple category documents
{ _id: ObjectId("4d6574baa6b804ea563c132a"),
title: "Epiphytes"
}
{ _id: ObjectId("4d6574baa6b804ea563c459d"),
title: "Greenhouse flowers"
}
then a product belonging to both categories will look like this:
{ _id: ObjectId("4d6574baa6b804ea563ca982"),
name: "Dragon Orchid",
category_ids: [ ObjectId("4d6574baa6b804ea563c132a"),
ObjectId("4d6574baa6b804ea563c459d") ]
}
for more: http://docs.mongodb.org/manual/reference/database-references/
Try looking at the problem inside-out: Instead of having items inside categories, have the items list the categories they belong into.
You'll be able to easily find all items that belong to a category (or even multiple categories), and there is no duplication nor any need to keep many instances of the same item updated.
This can be very fast and efficient, especially if you index the list of categories. Check out multikey indexes.
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)
As I can get specific field values ​​by querying with MongoId a document whose structure is as follows:
{
_id: ObjectId(xxx),
name: xxx,
subs: [{
_id: ObjectId(yyy),
name: yyy,
subs: [{
_id: ObjectId(zzz),
name: zzz,
subs: [...]
}]
}]
}
I need that, given a specific ObjectId obtaining an element that have the fields: _id, name
Note: a single document with all information.
regards
It seems like, with your current data model, that you would need to retrieve the top level document and then recursively search for the object you want inside of the document you retrieved.
There are many ways to store hierarchical data and I would suggest you take a look at the 10gen docs here, they are pretty thorough but I will summarize for you below.
Let's take a look at some of the ideas presented in that document starting with the good parts and drawbacks to your current approach.
Full Tree in Single Document (What you are doing now)
Pros:
Single document to fetch per page
One location on disk for whole tree
You can see full structure easily
Cons
Hard to search
Hard to get back partial results
Can get unwieldy if you need a huge tree. Further there is a limit on the size of documents in MongoDB – 16MB in v1.8 (limit may rise in future versions).
Your question relates directly to the problem of searching so, depending on your use case and desire to optimize, you probably either want to take the Array of Ancestors or the Materialized Path approach instead.
Array of Ancestors
With this approach you would store the ancestors of a document in an array and create an index on that field so that it was quickly and easily searchable.
Materialized Path
With this approach you would store the full path to the document as a string of ancestors and query via regular expression.
Make sense?
If you are building a tree structure in mongoid. I would suggest looking into
Mongoid Tree
it's nice gem that would give you all or a least most of things you need.
From Read Me:
class Node
include Mongoid::Document
include Mongoid::Tree
end
Node.root
Node.roots
Node.leaves
node.root
node.parent
node.children
node.ancestors
node.ancestors_and_self
node.descendants
node.descendants_and_self
node.siblings
node.siblings_and_self
node.leaves