Updating MongoDB nested array using same path as the search query - javascript

I have the following problem, I want to update a document with a path id.metadata.panels.items where panels is an array and items is an array. My search query looks at the items and displays only those that match the criteria of metadata.panels.items.member.type: 'owner' - then I want to update the 'owner to 'account'.
When I am trying to update having the search path same as update path I get an error message saying: cannot use the part metadata.panels.items.member.type to traverse the element.
The documents have their own
How can I resolve this problem?
I have already tried to go through the collection using nested forEach statements to iterate through each of the arrays but I am not sure what to do next.
var records = db.getCollection('sample').find({"metadata.panels.items.member.type":"
[owner]"})
records.forEach(function(id) {
var newFields = [];
metadata.panels.forEach(function(panel, panelIndex){
panels.items.forEach(function (item, itemIndex) {
})
})
})
Sample document structure:
{
"panels": [{
"name": "categories",
"items": [{
"member": {
"type": "[Owner]",
"subtype": "[Contractor]"
},
"format": {
"members": {}
}
}]
},
{
"name": "localisation",
"items": [{
"member": {
"city": "NY",
"state":"NY"
}
}]
}]
}
Expected result:
{
"panels": [{
"name": "categories",
"items": [{
"member": {
"type": "[Account]",
"subtype": "[Contractor]"
},
"format": {
"members": {}
}
}]
},
{
"name": "localisation",
"items": [{
"member": {
"city": "NY",
"state":"NY"
}
}]
}]
}

I figured it out.
var newFields = [];
var records = db.getCollection('sample').find({"metadata.panels.items.member.type":"
[owner]"})
records.forEach(function(id) {
metadata.panels.forEach(function(panel, panelIndex){
panels.items.forEach(function (item, itemIndex) {
// I have generated update statements as strings
// first list is always position 0 and this goes to the statement
// second list get's populated from itemIndex
// added them to the newFields list
})
})
})
newFields.forEach(function(i){
eval(i)
})

Related

Iterate through array of objects,not giving required output

given code
[
{
"data": [
{
"text_name": "test",
"text_url": "https://www.news18.com/topics/gold-prices/1",
"is_new": "1"
},
{
"text_name": "test2",
"text_url": "https://www.news18.com/topics/gold-prices/2",
"is_new": "0"
}
],
"slug": "bollywood",
"heading": "testing",
"status": "1",
"is_open_new": "1",
"order_data": "2",
"section_dropdown": "bollywood"
}
]
I want to iterate through this given code snippet and get the data.
const trendingTopicsData = trendingTopics.data
but this is showing null
Since the object in the snippet is an array, first you have to get the index of the item you want to work with (in this case the first item — index 0). Then you can iterate through the data array however you want (loop, forEach, map etc.).
Try:
const trendingTopicsData = trendingTopics[0].data
Here it is as a runnable snippet:
const trendingTopics = [
{
"data": [
{
"text_name": "test",
"text_url": "https://www.news18.com/topics/gold-prices/1",
"is_new": "1"
},
{
"text_name": "test2",
"text_url": "https://www.news18.com/topics/gold-prices/2",
"is_new": "0"
}
],
"slug": "bollywood",
"heading": "testing",
"status": "1",
"is_open_new": "1",
"order_data": "2",
"section_dropdown": "bollywood"
}
]
// Get trending topics data array
const trendingTopicsData = trendingTopics[0].data;
console.log("Data array:", trendingTopicsData)
// Iterate through each of the items in the data array
trendingTopicsData.forEach((dataItem, index) => console.log(`Data item #${index}:`, dataItem));
The object you are trying to access is inside an array. You will have to loop through the array
trendingTopics.forEach(topic => {
// do something with topic.data
})

Underscore.js where() function issue with searching json objects

I have a json collection stored as {"books": [{...}, ... ]} in a file. "books" is a list of json objects where each is a book. For example:
{
"books": [
{
"items": [
{
"id": "jD8iswEACAAJ",
"volumeInfo": {
"industryIdentifiers": [
{
"type": "ISBN_10",
"identifier": "0984782850"
},
{
"type": "ISBN_13",
"identifier": "9780984782857"
}
],
},
}
]
},
]
}
I have a need to read the json using _.where, specifically search every item in the collection for the "identifier" value of "type": "ISBN_10". Then return the full json object aka {"items": [...]}.
Suppose req.params.id is the "identifier" value (i.e. 0984782850).
This piece of code is not working
var _ = require('underscore');
...
app.get('/api/books/:id', function(req, res) {
var book = _.where(booksData.books.items[0].volumeInfo.industryIdentifiers[0], {identifier: req.params.id});
res.json(book);
});
it is returning
TypeError: Cannot read property '0' of undefined at position 43
The file has valid json, I have tried
var book = _.where(booksData.books, {items[0].volumeInfo.industryIdentifiers[0].identifier: req.params.id});
which also does not work
There is always one item in "items" and the ISBN_10 identifier is the first item in "industryIdentifiers" hence items[0].volumeInfo.industryIdentifiers[0].identifier
What am I doing wrong?
*EDIT: I tried with industryIdentifiers, but response is [ ]
Don't use industryIdentifiers[1]. You want to search the entire industryIdentifiers array, not a single object.
var book = _.where(booksData.books[0].items[0].volumeInfo.industryIdentifiers, {identifier: req.params.id})[0];
You also need books[0], since books is also an array.
const booksData = {
"books": [
{
"items": [
{
"id": "jD8iswEACAAJ",
"volumeInfo": {
"industryIdentifiers": [
{
"type": "ISBN_10",
"identifier": "0984782850"
},
{
"type": "ISBN_13",
"identifier": "9780984782857"
}
],
},
}
]
},
]
};
var book = _.where(booksData.books[0].items[0].volumeInfo.industryIdentifiers, {identifier: "0984782850"})[0];
console.log(book);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js"></script>

Search inside an object from the req.query

I have a nested object displayed in my view and i want to search in it from the query like this :
http://localhost:3000/test?$folder=folder
My object is like this :
const test = {
"item": [
{
"name": "folder",
"item": [{
"name": "subFolder",
"item": [
{
"name": "subFolderTest1",
"item": [{
"path": "/",
"items": [{
"method": "GET",
}]
}]
},
{
"name": "subFolderTest2",
"item": [{
"path": "/",
"items": [{
"method": "GET",
}]
}]
}
]
}]
}
]
}
If i have http://localhost:3000/test?$folder=folder then i would have :
{
{
"name": "subFolder",
"item": [{},{}]
}
}
And if i have http://localhost:3000/test?$folder=folder/subFolder then i will have :
{
{
"name": "subFolderTest1",
"item": [{}]
},
{
"name": "subFolderTest2",
"item": [{}]
}
}
I know how to get what's inside my query and what the user's input but i don't how to search and display from something which is already displayed.
If you already have your query string you could split it by the "/" character. Use the first name to find your first item, the second name to find the second, and so on.
var folder = "folder/subFolder";
var path = folder.split("/");
var currentItem = test["item"];
// Get each name you are looking for
path.forEach(function(name) {
// get each entry of the current item
currentItem.forEach(function(entry) {
// if the name of the entry is the same as the
// name you are looking for then this is the
// next item you are looking for
if (entry.name == name) {
currentItem = entry["item"];
}
});
});
// now currentItem should be the entry specified by your path
You will still have to add code to handle situations like not having the name you are looking for in your current item, or having multiple entries with the correct name, and so on. I just kept it simple for the sake of clarity.

Nested forEach issue

I have two arrays of object, the first array (printers, around 80 elements) is made of the following type of objects:
[{
printerBrand: 'Mutoh',
printerModel: 'VJ 1204G',
headsBrand: 'Epson',
headType: '',
compatibilty: [
'EDX',
'DT8',
'DT8-Pro',
'ECH',
],
cartridges: [],
},
....
]
The second array (cardridges, around 500 elements) is made of the following type of objects:
[
{
"customData": {
"brand": {
"value": {
"type": "string",
"content": "ECH"
},
"key": "brand"
},
"printer": {
"value": {
"type": "string",
"content": "c4280"
},
"key": "printer"
}
},
"name": "DT8 XLXL",
"image": {
"id": "zLaDHrgbarhFSnXAK",
"url": "https://xxxxxxx.net/images/xxxxxx.jpg"
},
"brandId": "xxxxx",
"companyId": "xxxx",
"createdAt": "2018-03-26T14:39:47.326Z",
"updatedAt": "2018-04-09T14:31:38.169Z",
"points": 60,
"id": "dq2Zezwm4nHr8FhEN"
},
...
]
What I want to do first is to is to iterate through the first array and and then iterate for all the cardridge available: if a the value customData.brand.value of a cardridge is included inside the array 'compatibility' of a printer, then I have to add this cardridge object inside the cardridges array of this printer. I have tried but somehow the iteration doesn't take place correctly. This is what I tried:
printers.forEach((printerItem) => {
const printer = printerItem;
printer.compatibilty.forEach((compatibilityItem) => {
const compatibility = compatibilityItem;
cardridges.forEach((cartridge) => {
if (compatibility === cartridge.customData.brand.value.content) {
printer.cartridges.push(cartridge);
}
});
});
});
What am I doing wrong?
You're accessing the wrong property. It should be cartridge.customData.brandName.value.content, carefully note brandName.value rather than brand.value
Your issue is that you're accessing it by the wrong property - brand and not brandName.
Furthermore, if you're targeting everything but IE, you could simplify your nested for loops to utilize some fancy ES6 array methods.
printers.forEach((p) => {
p.cartridges.push(cartridges.filter((c) => {
const brandName = c.customData.brandName.value.content;
return p.compatibilty.includes(brandName);
}));
});

Meteor Import JSON into Collection

I am trying to import a JSON file that has embedded objects into the MongoDB and would like to know how to format to import the doc correctly. To be clear the doc format must remain in its current form. I must modify/create a function or method that would allow this file to be imported with _id associated in the sport-events array loop (Ive shorted to one sports-event array for brevity). Perhaps a better way of putting the question is how could I import eveything in the sports-event array and leave the rest of the doc.
JSON Doc.
{
"sports-content": {
"sport-event": [{
"event-metadata": {
"league": "NCAA Basketball",
"event-type": "0",
"league-details": "NCAAB",
"event-date-time": "12/18/2015 07:00 PM",
"eventNum": "3000460",
"status": "",
"off-the-board": "False"
},
"team": [{
"team-metadata": {
"alignment": "Home",
"nss": "526",
"openNum": "526",
"name": {
"full": "Clemson"
}
},
"wagering-stats": {
"wagering-straight-spread": {
"bookmaker-name": "BetOnline",
"active": "true",
"line": "1.5",
"money": "-110",
"context": "current"
}
},
"team-stats": {
"score": "0"
}
}, {
"team-metadata": {
"alignment": "Away",
"openNum": "525",
"nss": "525",
"name": {
"full": "South Carolina"
}
},
"wagering-stats": {
"wagering-straight-spread": {
"bookmaker-name": "BetOnline",
"active": "true",
"line": "-1.5",
"money": "-110",
"context": "current"
}
},
"team-stats": {
"score": "0"
}
}]
}],
"sports-meta-data": {
"doc-time": "42353.5979256944"
}
}
}
Meteor server.js under Meteor.startup
if (SportEventsFeed.find().count() === 0) {
console.log("Importing private/products.json to db")
var data = JSON.parse(Assets.getText("ncaab.json"));
data.forEach(function (item, index, array) {
SportEventsFeed.insert(item);
})
}
Here is how you can just insert the items from the 'sports-event' array as individual documents in the db.
I'm not sure if the index value is what you wanted for the _id field, if not change the value assigned to item_id (or comment out this line for a default _id).
if (SportEventsFeed.find().count() === 0) {
console.log("Importing private/products.json to db")
var data = JSON.parse(Assets.getText("ncaab.json"));
data['sports-content']['sports-event'].forEach(function (item, index, array) {
item._id = index;
SportEventsFeed.insert(item);
})
}

Categories