Duplicating a Mongoose document with subdocs, duplicated id of subdocs are allowed? - mongodb

To clarify: I have a document with a subdoc. I create a new document with the same data of the other one and it gets a new id. However, when I copy the subdoc array they do not get a new id.
Are subdocs id local to the parent doc? I.e. would the following be a problem?
[
{
"__v": 1,
"_id": "5214af03a9f53efa61000004",
"name": "Foo",
"subdocs": [
{
"thing": "value",
"_id": "5214af03a9f53efa61000006"
}
]
},
{
"__v": 0,
"name": "Foo",
"_id": "5214af03a9f53efa61000014",
"subdocs": [
{
"thing": "value",
"_id": "5214af03a9f53efa61000006"
}
]
}
]

There is a unique index on the _id field of documents stored directly in a collection, but not for embedded documents, nor is there any requirement that embedded documents have an _id field at all. The two documents you have provided are both valid to be stored in MongoDB in the same database (I'm interpreting your example as an array of two documents that are both stored directly in a collection together).

Related

Pymongo access specific field value within nested dict

In Pymongo application, while iterating through every document of the collection, how to access a specific field value of the JSON structure?
{
"_id": {
"$oid": "5e1c2b0bacbdaehujjjbdsh"
},
"a": {
"data_type": "abc",
"data_format": "xyz",
"data_version": "1",
},
"b": "123",
"c": "345"
}
Based on the following code snippet, how do I access the value associated with the key 'data_format' which is nested within the key 'a' ---
for document in col.find():
data_format_val = document['a']['data_format'] # not working
Relatively new to Mongodb query commands.
It's possible that some of the documents of the collection may not have the key 'a'.
Try using $exists to make sure the field is present like this: Syntax: { field: { $exists: } }

Create dependencies between documents in MongoDB

I want to create a dependency between some documents in my collection.
For example I have document A, and I want to use some fields of it in document B as a subsection. So if I change document A, the fields that are also in document B will also change.
Here's a better explanation with actual JSONs:
Here's document A
{
"_id": ObjectId("1"),
"value": 10,
"name": "A_document_name",
"owner": "some_owner"
}
Here's document B
{
"_id": ObjectId("2"),
"description": "some_description",
"valid": true,
"name": "some_name",
"items": [
{
"id": "1",
"name": "A_object_name"
}
]
}
Now, what I want to happen is, if I change the name of document A, I want to see that it also changed in the items section of document B. Currently, when I change A's name, it changes only in A and B remains the same since it was created. Is it achievable in Mongo? How can I create a reference between items section in B with A? Do I need to change something in my document structure?
You need to use mongoDB's $lookup
You you'd a unique identifier from that you can use match the documents,
e.g:
The A document would be:
{
"_id": ObjectId("1"),
"b_id": ObjectId("2"),
"value": 10,
"name": "A_document_name",
"owner": "some_owner"
}
While the B document would just be:
{
"_id": ObjectId("2"),
"description": "some_description",
"valid": true,
"name": "some_name"
}
You'll then do an aggregate query like so:
db.B.aggregate([
{
$lookup:
{
from: "A", //The collection you're getting the items from
localField: "_id", //The local field you're using to lookup
foreignField: "b_id", //The field the `A` document you're using to match
as: "items" //The name of the field that will be populated with the results
}
}
])
There's a lot more you can do with aggregate take a minute to look through the docs. Let me know if this helps.

How to make a cloudant query to find documents which two fields are equal

I need to get all documents whose e.g. "_id" field equal to another document field, e.g. "appId"
{
"_id": "xxxx-xxxx-xxxx-xxxx",
"_rev": "xxxx-xxxx-xxxx-xxxx",
"header": {
"appId": "xxxx-xxxx-xxxx-xxxx"
So what would be the query?
"selector": {
"_id": {
"$eq": header.appId
}
},
You can't do "sub queries" with Mango.
From what I see, you're trying to get all the documents listed by appId.
This could be done by using a view.
Your map function would be the following:
if(doc.header && doc.header.appId){
emit(doc.doc.header.appId,{_id: doc.header.appId});
}
The result would be a list of documents mapped by doc.header.appId.
If you query the view with ?include_docs=true, the documents would be joined to the response since we're doing a ManyToJoin join.

mongodb: return an array of document ids

Is it possible to query mongodb to return array of matching document id values, without the related keys?
Please consider following 'parent' data structur:
{
"_id": ObjectId("52448e4697fb2b775cb5c3a7"),
"name": "Peter",
"children": [
{
"name": "joe"
}
]
},
{
"_id": ObjectId("52448e4697fb2b775cb5c3b6"),
"name": "Marry",
"children": [
{
"name": "joe"
}
]
}
I would to query for an array of parent _ids whose children have the name "joe"
For provided sample data, I would like the following output returned from mongo:
[ObjectId("52448e4697fb2b775cb5c3a7"), ObjectId("52448e4697fb2b775cb5c3b6")]
I know that I can query for an output like this, which also contains the keys
[{"_id": ObjectId("52448e4697fb2b775cb5c3a7")}, {"_id": ObjectId("52448e4697fb2b775cb5c3b6")}]
However I need to push above array to another document with an update operation like this:
db.statistic.update({"date": today}, {$push: {"children": [ObjectId("52448e4697fb2b775cb5c3a7"), ObjectId("52448e4697fb2b775cb5c3b6")]}}, true, false)
I would like to avoid sorting out the document structure, in case it is possible to just return an array containing the appropriate values using mongo
It should be possible by
db.coll.distinct("_id", {"children.name": "joe"})

MongoDB and complex query on ordered arrays

I've the following entity persisted on mongo in a users collection:
{
"fullname": "Luke Tomson",
"nicknames": [
{
"name": "lukeone",
"created": ISODate("2011-05-18T19:42:56.411Z")
},
{
"name": "magicluke",
"created": ISODate("2012-01-12T19: 42: 56.411Z")
},
{
"name": "superluke",
"created": ISODate("2012-03-27T19: 42: 56.411Z")
}
}
]
}
How do I get the last nickname name for a user whose fullname is "Luke Tomson" ? And more specifically, how do I retrieve in the mongo shell a specific index (the first or the last) of a sorted array that was sorted upon a specific field (in this case, created).
Thanks
From the documentation, the second object passed to a .find is a selection of what portions of the object you want returned.
So, what you want is basically:
db.users.find({"fullname": "Luke Tomson"}, {"nicknames": { $slice: -1 } });
Though you might also want to return the _id if there are multiple "Luke Tomson"s in your DB and you need to uniquely identify them.