Cannot get data from a js array with Node js - arrays

I have a js object array like this.
[
{
name:"Japanilainen ravintola Koto",
rating:3.9,
photo:[
{
height:2160,
html_attributions:[
"Hannes Junnila"
],
photo_reference:"CoQBdwAAAMDlivT0nOnYg8jC1txZ3RbfBR59XvKN0WphDbRVUXaUTQclzzaIaXJ8-p7s3x_aG67AUsM_HLNML6pzGl3v_wV2D-eudH_3wy2cB1ROrRgGcGyf4lRuNpE3WwXYbYZu6EK8oEPiJ5B17Lybj-eVbYM2EgVVBgOrUJhsblY1mfxWEhAZ4oHCFakH-hgkbksfGa2uGhQe4aUeOrS2isAir01KUwQ7N3Ce2Q",
width:2269
}
]
},
{
name:"Kin Sushi Helsinki",
rating:4.2,
photo:[
{
height:2988,
html_attributions:[
"Stephan Winter"
],
photo_reference:"CoQBdwAAAN4iMumSbQjtRnJIH1AKRdbSfnI02WGh11r1xaVnZl1ohebKp6zpAS4mmJFqTagrIqUJ39kzulVI0sz2UzzfaVdsAFc5f80PnOCzSLqL5gnpsqv90dVJIqUWD3Bcc9TgYPPs3oGwyekkOsmjQ59o9yqdoF5GzrpaKkojhMNLxpfzEhBKpRkA2CzINpUzAAe3e90TGhQ_KbYCmtJYLfVGIu1kZkzQIAwE4A",
width:5312
}
]
}
]
I get this array above by doing this for each.
response.results.forEach((entry)=>{
var restaurantName = {
"name" : entry.name,
"rating" : entry.rating,
"photo_reference" : entry.photos
}
arr.push(restaurantName);
});
res.send(arr);
And I send the array to my browser so I can see it.
What I am trying to do is to get photo_reference from the entry.photos
I tried entry.photos[0].photo_reference and many more ways and in all of them I am getting a cannot read properly, and now I am not sure how to get that information out.

I edited some of the variable names to make it easier to simulate here, but just map the objects in the photo arrays to their references, and you'll get an array of photo references.
const data = [
{
name:"Japanilainen ravintola Koto",
rating:3.9,
photo:[
{
height:2160,
html_attributions:[
'Hannes Junnila'
],
photo_reference:"CoQBdwAAAMDlivT0nOnYg8jC1txZ3RbfBR59XvKN0WphDbRVUXaUTQclzzaIaXJ8-p7s3x_aG67AUsM_HLNML6pzGl3v_wV2D-eudH_3wy2cB1ROrRgGcGyf4lRuNpE3WwXYbYZu6EK8oEPiJ5B17Lybj-eVbYM2EgVVBgOrUJhsblY1mfxWEhAZ4oHCFakH-hgkbksfGa2uGhQe4aUeOrS2isAir01KUwQ7N3Ce2Q",
width:2269
}
]
},
{
name:"Kin Sushi Helsinki",
rating:4.2,
photo:[
{
height:2988,
html_attributions:[
'Stephan Winter'
],
photo_reference:"CoQBdwAAAN4iMumSbQjtRnJIH1AKRdbSfnI02WGh11r1xaVnZl1ohebKp6zpAS4mmJFqTagrIqUJ39kzulVI0sz2UzzfaVdsAFc5f80PnOCzSLqL5gnpsqv90dVJIqUWD3Bcc9TgYPPs3oGwyekkOsmjQ59o9yqdoF5GzrpaKkojhMNLxpfzEhBKpRkA2CzINpUzAAe3e90TGhQ_KbYCmtJYLfVGIu1kZkzQIAwE4A",
width:5312
}
]
}
]
const arr = []
data.forEach((entry)=>{
var restaurantName = {
"name" : entry.name,
"rating" : entry.rating,
"photo_reference" : entry.photo.map(x => x.photo_reference)
}
arr.push(restaurantName);
});
console.log(arr);

entry.photoes is not defined in your response.results object array.. did you mean to access it as entry.photo (inside your foreach function) ?

Related

How can I realize "find" with using "$in" by two parameters in mangoose?

Hi I have the function which get object with id array like this.
{
"participants": [
"5fa566b5b96a9407c804ccd4",
"5fa5639cb96a9407c804ccce"
]
}
And I need to find object which have exactly this fields
Objects in which i try to find it looks like this:
{
"_id" : ObjectId("5fac288e53a6a72e94f721fa"),
"participants" : [
ObjectId("5fa566b5b96a9407c804ccd5"),
ObjectId("5fa5639cb96a9407c804ccc5")
],
"messages" : [],
}
I am trying to do like this but it doesn't work.
async filterDialog(newDialog: any){
const res = await Dialog.find({
'participants': { $in: { ...newDialog.participants } }, function(err: any, dialog: any) {
if (err) {
return err
} else {
return dialog
}
},
})
return res;
}
Will be glad if someone help me.
I think you need $all operator.
Check this query:
db.collection.find({
"participants": {
"$all": yourArray
}
})
Only return the document where the field participants contains all element from the given array.
Example here where I've used numbers instead of ObjectId to read easier.
Please check if this is the behavior you expect.

Typescript - Querying or flattening nested array but keeping some objects as nested ones

Again I'm stuck with a nested Array of objects. I want to flatten it out, but I do have to keep some nested objects. The Problem I'm running into: How to rename the keys of the nested objects since I have an undefined number of nested objects. There might be 3 of them oder 8. So property1_3 has to be renamed to eg property1_3_1, property1_3_2 - depending on how many objects are in the original json data. And how to aply them to the correct parent object.
The json data I recieve looks like:
data = [{
"property1_1": "value1_1",
"property1_2": "value1_2",
"property1_3": [
[{
"subproperty1_1_1": "subvalue1_1_1",
"subproperty1_1_2": "subvalue1_1_2"
}],
[{
"subproperty1_2_1": "subvalue1_2_1",
"subproperty1_2_2": "subvalue1_2_2"
}]
]
},
{
"property2_1": "value2_1",
"property2_2": "value2_2",
"property2_3": [
[{
"subproperty2_1_1": "subvalue2_2_1",
"subproperty2_1_2": "subvalue2_2_2"
}],
[{
"subproperty2_2_1": "subvalue2_2_1",
"subproperty2_2_2": "subvalue2_2_2"
}],
[{
"subproperty2_3_1": "subvalue2_2_1",
"subproperty2_3_2": "subvalue2_2_2"
}]
]
}
]
What I want to achieve now is:
data = [
{
"property1_1": "value1_1",
"property1_2": "value1_2",
"property1_3_index1": {"subproperty1_1_1":"subvalue1_1_1", "subproperty1_1_2":"subvalue1_1_2"},
"property1_3_index2": {"subproperty1_2_1":"subvalue1_2_1", "subproperty1_2_2":"subvalue1_2_2"}
},
{
"property2_1": "value2_1",
"property2_2": "value2_2",
"property2_3_index1": {"subproperty2_1_1":"subvalue2_2_1", "subproperty2_1_2":"subvalue2_2_2"},
"property2_3_index2": {"subproperty2_2_1":"subvalue2_2_1", "subproperty2_2_2":"subvalue2_2_2"},
"property2_3_index3": {"subproperty2_3_1":"subvalue2_2_1", "subproperty2_3_2":"subvalue2_2_2"}
}
]
My last try was:
transformData(input) {
const testArray = [];
input.map(obj => {
for (const prop in obj) {
if (obj.hasOwnProperty(prop) && Array.isArray(obj[prop])) {
for (const [index, element] of obj[prop].entries()) {
testArray.push(element[0]);
}
}
}
});
}
but this only leeds to an array with all the single subobjects in one array. I'm also not quite sure if it's best trying to convert the original data or to build a new array as I tried before.
I finally found a way to achieve this.
transformData(input) {
return input.map(obj => {
for (const prop in obj) {
if (obj.hasOwnProperty(prop) && Array.isArray(obj[prop])) {
for (let i = 0; i < obj[prop].length; i++) {
const name = prop + (i + 1).toString();
obj[name] = obj[prop].flat(1)[i];
}
delete obj[prop];
}
}
return obj;
});
}

Add array values into MongoDB where element is not in array

In MongoDB, this is the simplified structure of my account document:
{
"_id" : ObjectId("5a70a60ca7fbc476caea5e59"),
"templates" : [
{
"name" : "Password Reset",
"content" : "AAAAAAAA"
},
{
"name" : "Welcome Message",
"content" : "BBBBBB"
}
]
}
There's a similar default_templates collection
let accnt = await Account.findOne({ _id: req.account._id }, { templates: 1 });
let defaults = await DefaultTemplate.find({}).lean();
My goal is to find the missing templates under account and grab them from defaults. (a) I need to upsert templates if it doesn't exist in an account and (b) I don't want to update a template if it already exists in an account.
I've tried the following:
if (!accnt.templates || accnt.templates.length < defaults.length) {
const accountTemplates = _.filter(accnt.templates, 'name');
const templateNames = _.map(accountTemplates, 'name');
Account.update({ _id: req.account._id, 'templates.name' : { $nin: templateNames } },
{ '$push': { 'templates': { '$each' : defaults } } }, { 'upsert' : true },
function(err, result) {
Logger.error('error %o', err);
Logger.debug('result %o', result);
}
);
}
This succeeds at the upsert but it will enter all default templates even if there's a matching name in templateNames. I've verified that templateNames array is correct and I've also tried using $addToSet instead of $push, so I must not understand Mongo subdoc queries.
Any ideas on what I'm doing wrong?
Edit: I've gotten this to work by simply removing elements from the defaults array before updating, but I'd still like to know how this could be accomplished with Mongoose.
You can try with bulkWrite operation in mongodb
Account.bulkWrite(
req.body.accountTemplates.map((data) =>
({
updateOne: {
filter: { _id: req.account._id, 'templates.name' : { $ne: data.name } },
update: { $push: { templates: { $each : data } } },
upsert : true
}
})
)
})

logstash filter to modify array field

I am looking for a logstash filter that can modify array fields.
For example, I would like a modifier that can turn this JSON document
{
arrayField: [
{
subfield: {
subsubfield: "value1"
}
},
{
subfield: {
subsubfield: "value2"
}
}
]
}
Into this JSON document
{
arrayField: [
{
subfield: "value1"
},
{
subfield: "value2"
}
]
}
I have tried the following input
input {
mutate {
replace => ["[arrayField][subfield]", "%{[arrayField][subField][subsubField]}"]
}
}
but the input just rewrites the array field instead of operating on each element of the array. How do you set up a modifier to operate on each element of an array?
Thanks Alain Collins for pointing out the ruby filter. The below input did the trick.
input {
ruby {
code => "
event['arrayField'].each{|subdoc| subdoc['subfield'] = subdoc['subfield']['subsubfield']}
"
}
}

SwiftyJSON Append new data to existing JSON array

I am working on a way to add new JSON data to my existing JSON array:
var resources: JSON = [
"resources": []
]
override func viewDidLoad() {
super.viewDidLoad()
getApiResourceA() { responseObject, error in
var resourceA: JSON = [
"resourceA": []
]
let resourceAResponseObject = JSON(responseObject!)
resourceA["resourceA"] = resourceAResponseObject
self.resources["resources"] = resourceA
}
getApiResourceB() { responseObject, error in
var resourceB: JSON = [
"resourceB": []
]
let resourceBResponseObject = JSON(responseObject!)
resourceB["resourceB"] = resourceBResponseObject
self.resources["resources"] = resourceB
}
}
The structure I am trying to get is:
{
"resources": {
"resourceA": {
"id": 1
"name": "Name1"
}
"resourceB": {
"id": 2
"name": "Name2"
}
}
}
But in my code there are two different "resources"-array created...
Anyone know how to deal with this?
First it is important to understand that JSON is Struct means it is duplicated every time you pass it or use it.
Another issue, you declared resources as Array and not as Dictionary means you can use resource as key.
Declare extensions:
extension JSON{
mutating func appendIfArray(json:JSON){
if var arr = self.array{
arr.append(json)
self = JSON(arr);
}
}
mutating func appendIfDictionary(key:String,json:JSON){
if var dict = self.dictionary{
dict[key] = json;
self = JSON(dict);
}
}
}
use:
//notice the change [String:AnyObject]
var resources: JSON = [
"resources": [String:AnyObject](),
]
resources["resources"].appendIfDictionary("resourceA", json: JSON(["key1":"value1"]))
resources["resources"].appendIfDictionary("resourceB", json: JSON(["key2":"value2"]))
result:
{
"resources" : {
"resourceB" : {
"key2" : "value2"
},
"resourceA" : {
"key1" : "value1"
}
}
}
#daniel-krom has right, but is a little confusing implement the extension, so, we need only add at the end of the Swift controller (or class) that code that adds the "append" methods, nothing else.
Using the appendIfArray method, I could pass from this
[
{
"id_usuario" : 2
}
]
...to this
[
{
"id_usuario" : 2
},
{
"id_usuario" : 111
},
{
"id_usuario" : 112
},
{
"id_usuario" : 113
}
]
The complete code is below:
do{
try json2!["usuarios"][indice]["fotos"][0]["me_gusta"].appendIfArray(json: JSON( ["id_usuario": 111] ))
try json2!["usuarios"][indice]["fotos"][0]["me_gusta"].appendIfArray(json: JSON( ["id_usuario": 112] ))
try json2!["usuarios"][indice]["fotos"][0]["me_gusta"].appendIfArray(json: JSON( ["id_usuario": 113] ))
}catch {
print("Error")
}
The complete JSON structure can find in
http://jsoneditoronline.org/?id=56988c404dcd3c8b3065a583f9a41bba
I hope this can be useful

Resources