Convert nested document collection to model tree structure with parent references - javascript

I need to convert a collection with nested documents to a model tree structure with parent references. So this is how my structure looks like:
{
"_id" : "sdaGREsfRdfGdFdwG",
"docTitle" : "Document 1",
"group" : [
{
"id" : "cdPhkTpMXi8z6TqMT"
"title" : "title 1",
"data" : [
{
"id" : "Nkspf5kKfPo3axeJA",
"some" : "data",
"other" : "things",
"and" : "so on",
},
{
"id" : "Ca8ncFgq83RoeD8he",
"some" : "data",
"other" : "things",
"and" : "so on",
},
{
"id" : "vyjgkuNXRN9KkCd5o",
"some" : "data",
"other" : "things",
"and" : "so on",
}
],
},
{
"id" : "TuibXPe5qMvqdMW6q"
"title" : "title 2",
"data" : [
{
"id" : "f5L5zsSNRSQKWoAXL",
"some" : "data",
"other" : "things",
"and" : "so on",
}
],
}
]
}
As you can see, there is a group array, which has also a data array. Now I need a main document like this:
{
"_id" : "sdaGREsfRdfGdFdwG",
"docTitle" : "Document 1"
}
And the next child elements, which would be:
{
"id" : "cdPhkTpMXi8z6TqMT"
"title" : "title 1",
"type" : "group",
"parent" : "sdaGREsfRdfGdFdwG"
},
{
"id" : "TuibXPe5qMvqdMW6q"
"title" : "title 2",
"type" : "group",
"parent" : "sdaGREsfRdfGdFdwG"
}
At least the data elements, which are children of the group-elements:
{
"id" : "Nkspf5kKfPo3axeJA",
"some" : "data",
"other" : "things",
"and" : "so on",
"type" : "element",
"parent" : "cdPhkTpMXi8z6TqMT"
},
{
"id" : "Ca8ncFgq83RoeD8he",
"some" : "data",
"other" : "things",
"and" : "so on",
"type" : "element",
"parent" : "cdPhkTpMXi8z6TqMT"
},
{
"id" : "vyjgkuNXRN9KkCd5o",
"some" : "data",
"other" : "things",
"and" : "so on",
"type" : "element",
"parent" : "cdPhkTpMXi8z6TqMT"
},
{
"id" : "f5L5zsSNRSQKWoAXL",
"some" : "data",
"other" : "things",
"and" : "so on",
"type" : "element",
"parent" : "TuibXPe5qMvqdMW6q"
}
So my attempt would be something like this:
Collection.find({}).forEach(function(doc) { // get all documents
var docID = doc._id;
doc.group.forEach(function(group) { // get all groups
var parent = group.id;
group.type = "group";
group.parent = docID;
group.data.forEach(function(element) { // get all elements
element.type ="element";
element.parent = parent;
});
});
});
1) I don't know how to do that in a better way
2) And I don't know how to save the result back to the collection

Fot the groups:
db.myCol.aggregate([{$unwind:"$group"},
{$project:{_id:"$group.id", some:"$group.some",
parent:"$_id", type:{$literal:"group"}}}])
For the Elements:
db.myCol.aggregate([{$unwind:"$group"},
{$unwind:"$group.data"},
{$project:{_id:"$group.data.id", some:"$group.data.some",
parent:"$group.id", type:{$literal:"element"}}}])
And to your second question: You can add an $out step to the aggregation pipeline at the end. For example: {$out:"outputCol"}

Related

How to update the values of a "Key-Value" pair in a nested array in MongoDB without adding a new element

I have the following data:-
**{
"_id" : ObjectId("5bf8048768d1e82d8bb4a477"),
"customer_code" : "c100003",
"vm_info" : [
{
"instanceId" : "i-0495d75742b839858",
"tags" : [
{
"Key" : "SIDs",
"Value" : "NWS"
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OS_VERSION",
"Value" : "10"
}
]
},
{
"instanceId" : "i-017488cffca28cd70",
"tags" : [
{
"Key" : "OS_VERSION",
"Value" : "10"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "SIDs",
"Value" : "NWS"
}
]
},
{
"instanceId" : "i-09d5db81657fe35d8",
"tags" : [
{
"Key" : "SIDs",
"Value" : "NWS"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "OS_VERSION",
"Value" : "10"
}
]
}
]
}**
Now i want to update the value of "OS_VERSION" to "12" instead of "10". After updating it should look like this:-
**{
"_id" : ObjectId("5bf8048768d1e82d8bb4a477"),
"customer_code" : "c100003",
"vm_info" : [
{
"instanceId" : "i-0495d75742b839858",
"tags" : [
{
"Key" : "SIDs",
"Value" : "NWS"
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OS_VERSION",
"Value" : "12"
}
]
},
{
"instanceId" : "i-017488cffca28cd70",
"tags" : [
{
"Key" : "OS_VERSION",
"Value" : "10"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "SIDs",
"Value" : "NWS"
}
]
},
{
"instanceId" : "i-09d5db81657fe35d8",
"tags" : [
{
"Key" : "SIDs",
"Value" : "NWS"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "OS_VERSION",
"Value" : "10"
}
]
}
]
}**
When i use Update operator with "$addToSet" a new Key-Value pair is added instead of updating the existing data like this:
**{
"_id" : ObjectId("5bf8048768d1e82d8bb4a477"),
"customer_code" : "c100003",
"vm_info" : [
{
"instanceId" : "i-0495d75742b839858",
"tags" : [
{
"Key" : "SIDs",
"Value" : "NWS"
},
{
"Key" : "OSTYPE",
"Value" : "WINDOWS"
},
{
"Key" : "BACKUP_SERVER_LOCATION",
"Value" : ""
},
{
"Key" : "OS_VERSION",
"Value" : "10"
},
{
"Key" : "OS_VERSION",
"Value" : "12"
}
]
}
]
}** I don't want it to be added as a new element ,instead it should just update the existing element.
How can i achieve the desired result. Can someone help on this.
first remove that key-value pair and and insert new one.

Changing order of object in object array with an element key in mongo collection object

I want to change order of objects in slides sub document with respect to the sort_order key in it.
For Eg: I want to move slide with title A3 above A2. ie. sort_order value of A3 (3) is changed to 2 and that of A2 will be changed to 3, and viceversa in case of moving down.
How to do ??
Below is the db object.
{
"_id" : ObjectId("5a3b8cc68884dd1140a9a5b8"),
"title" : "Sort Test",
"user_id" : ObjectId("59e08e45f081170f582e95cc"),
"status" : "active",
"slides" : [
{
"_id" : ObjectId("5a3b8cc68884dd1140a9a5b9"),
"sort_order" : 0,
"content" : "Sort Test",
"title" : "Sort Test"
},
{
"_id" : ObjectId("5a3b8cda8884dd1140a9a5ba"),
"sort_order" : 1,
"content" : "Text Contents here...",
"title" : "A1"
},
{
"_id" : ObjectId("5a3b8ce48884dd1140a9a5bb"),
"sort_order" : 2,
"content" : "Text Contents here...",
"title" : "A2"
},
{
"_id" : ObjectId("5a3b8cec8884dd1140a9a5bc"),
"sort_order" : 3,
"content" : "Text Contents here...",
"title" : "A3"
},
{
"_id" : ObjectId("5a3b8cec8884dd1140455bc"),
"sort_order" : 4,
"content" : "Text Contents here...",
"title" : "A4"
}
],
"description" : "Sort Test",
"__v" : 0
}
With this method you can create a new array with same elements and the ones you ask for, switched (I think is what you asked).
Then you just have to update slides field in the DB with new array.
var dbObject = {
"_id" : ObjectId("5a3b8cc68884dd1140a9a5b8"),
"title" : "Sort Test",
"user_id" : ObjectId("59e08e45f081170f582e95cc"),
"status" : "active",
"slides" : [
{
"_id" : ObjectId("5a3b8cc68884dd1140a9a5b9"),
"sort_order" : 0,
"content" : "Sort Test",
"title" : "Sort Test"
},
{
"_id" : ObjectId("5a3b8cda8884dd1140a9a5ba"),
"sort_order" : 1,
"content" : "Text Contents here...",
"title" : "A1"
},
{
"_id" : ObjectId("5a3b8ce48884dd1140a9a5bb"),
"sort_order" : 2,
"content" : "Text Contents here...",
"title" : "A2"
},
{
"_id" : ObjectId("5a3b8cec8884dd1140a9a5bc"),
"sort_order" : 3,
"content" : "Text Contents here...",
"title" : "A3"
},
{
"_id" : ObjectId("5a3b8cec8884dd1140455bc"),
"sort_order" : 4,
"content" : "Text Contents here...",
"title" : "A4"
}
],
"description" : "Sort Test",
"__v" : 0
}
var slides = dbObject.slides;
var switchElementsInArray = function(array, sortOrder1, sortOrder2) {
var newArray = [];
for(var element of array) {
if(element.sort_order === sortOrder1) {
newArray.push(elem2);
} else if(element.sort_order === sortOrder2) {
newArray.push(elem1);
} else {
newArray.push(element);
}
}
return newArray;
}
var newSlides = switchElementsInArray(slides, 2, 3);

Delete an array containing Objects MongoDB

I'm working in a project oj NodeJS, and I want to delete an element of array containing objets.
The Schema is:
{
"products" : [
{
"productid" : 1,
"name" : "product 1",
"price" : 200
},
{
"productid" : 2,
"name" : "product 2",
"price" : 300
},
{
"productid" : 3,
"name" : "product 3",
"price" : 350
},
{
"productid" : 4,
"name" : "product 4",
"price" : 300
},
,
{
"productid" : 5,
"name" : "product 5",
"price" : 300
}
]
}
And i want to delete product 3, how is query in mongodb? the "productid" attribute is key, does not repeat it
Thanks.
Use this:
Change collection name and {} as per your need.
db.collection.update( {}, { "$pull" : { "products" : { "productid" : 3 } } });
if it matches multiple element then use multi option like
db.collection.update( {}, { "$pull" : { "products" : { "productid" : 3 } } },
{ multi: true });
db.collection.update( {<query>}, { "$pull" : { "products.productid" : 3 } });

Modifying a JSON Object

I have a JSON generated by Papa Parse from a CSV file that look like this:
{ object, object, object, .... , object }
I need to modify it so it looks like this:
{ "publication" :
{
"id" : 1,
"name" : "name1"
},
"publication" :
{
"id" : 2,
"name" : "name2"
},
"publication" :
{
"id" : 3,
"name" : "name3"
}
}
Where the "id" and "name" are properties within each object.
In other words, I need a JSON that say "publication" and each "publication" occurrence have nested under it the properties names and values of one of the objects above.
How could I achieve this with Javascript?
Thanks
you cannot put many keys with same name...
a solution it's put in array
{
"publication" : [
{
"id" : 1,
"name" : "name1"
},
{
"id" : 2,
"name" : "name2"
},
{
"id" : 3,
"name" : "name3"
}]
}
Is this not an array of publications?
{ publications: [{"id":1, "name":"name1"},
{"id":2, "name":"name2"}.....]}
If I understand it right, you probably mean that you have objects like this:
{"publication" : { "id" : 1, "name" : "name1" }
{"publication" : { "id" : 2, "name" : "name2" }
{"publication" : { "id" : 3, "name" : "name3" }
What you can do in order to have:
{ "publication" : [
{
"id" : 1,
"name" : "name1"
},
{
"id" : 1,
"name" : "name2"
},
{
"id" : 3,
"name" : "name3"
} ]
}
is:
var json = [{"publication" : { "id" : 1, "name" : "name1" }},
{"publication" : { "id" : 2, "name" : "name2" }},
{"publication" : { "id" : 3, "name" : "name3" }}];
var newJson = {"publication" : []};
var i = 0;
for (var item in json) {
var key = json[item];
var obj = {"id" : key["publication"]["id"], "name" : key["publication"]["name"]};
newJson["publication"][i] = obj;
i++;
}
You can check this if you want to print "pretty":
How can I pretty-print JSON using JavaScript?

show json with jstree 3.0

I've been trying to load a json file from apache, and show it's result with jstree, 3.0.0.
Here is my code:
$(function () {
$('#showTree').jstree({
'core' : {
'data' : {
'url' : function (node) {
return node= 'miley.json';
},
'data' : function (node) {
return { 'id' : node.id };
}
}
}
});
});
Know miley:
[
{ "id" : "ajson1", "parent" : "national", "text" : "Simple root node" },
{ "id" : "ajson2", "parent" : "le", "text" : "Root node 2" },
{ "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" },
{ "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" },
]
My console swears it receives the json, but i don't have a clue on finally showing the tree.
What am i missing? Any one help me? Thanks!!
Ivan Bozhanov, the jsTree plug in creator, answered me quickly at the jsTree google forums...
Here is my working code:
$('#showTree').jstree({
'core' : {
'data' : {
'url': 'miley.json',
'data' : function (node) {
return { 'id' : node.id };
}
}
}
});
Also, i made some changes to miley, and deleted the last comma in the first miley.json I posted above...:
[
{ "id" : "ajson1", "parent" : "#", "text" : "Simple root node" },
{ "id" : "ajson2", "parent" : "ajson1", "text" : "Root node 2" },
{ "id" : "ajson3", "parent" : "ajson2", "text" : "Child 1" },
{ "id" : "ajson4", "parent" : "ajson2", "text" : "Child 2" }
]

Categories