Pull out certain nested objects - javascript

I have a series of nested objects like this:
data = {"12345":{"value":{"1":"2","3":"4"}},
{"12346":{"value":{"5":"6","7":"8"}},
{"12347":{"value":{"9":"0","11":"22"}}
I would like to create a function to grab certain objects within this grouping. For example...
grabObject(12345);
would return:
{"value":{"1":"2","3":"4"}}
Any help you could provide would be great.

You don't need anything more than this:
function grabObject(id) {
return data[id];
}
After making some fixes to your syntax, here's a working jsFiddle: http://jsfiddle.net/jfriend00/04no0bvm/

var data = [
{
"12345": {
"value": {
"1": "2",
"3": "4"
}
}
},
{
"12346": {
"value": {
"5": "6",
"7": "8"
}
}
},
{
"12347": {
"value": {
"9": "0",
"11": "22"
}
}
}
];
function grabObject(id) {
var result;
for (i = 0; i < data.length; i++) {
for (var k in data[i]){
if(k == id) {
result = data[i][k];
}
}
}
return result;
}
console.log(grabObject('12345'));
This is the code I tested check and let me know

Related

Building multi-level aggregation queries using elastic-builder.js

I am trying to get my hands on javascript and elasticsearch and I was trying to create queries using the elastic-builder javascript lib.
I might be missing something which I am trying to figure out but unfortunately I am unable to.
Problem: I am trying to create multilevel aggregation like below,
"aggs": {
"1": {
"date_histogram": {
"field": "f1",
"calendar_interval": "1D"
},
"aggs": {
"2": {
"date_histogram": {
"field": "f2",
"calendar_interval": "1D"
},
"aggs": {
"3": {
"date_histogram": {
"field": "f3",
"calendar_interval": "1D"
}
}
}
}
}
}
But what I get instead is this:
"aggs": {
"1": {
"date_histogram": {
"field": "f1",
"calendar_interval": "1D"
},
"aggs": {
"2": {
"date_histogram": {
"field": "f2",
"calendar_interval": "1D"
}
},
"3": {
"date_histogram": {
"field": "f3",
"calendar_interval": "1D"
}
}
}
}
The current output I get has two aggregations nested in one. I am trying to build it using an array with aggregations defined in it.
The code I used is below:
let a = [
esb.dateHistogramAggregation('1', "d[key]['field']").calendarInterval('1D'),
esb.dateHistogramAggregation('2', "d[key]['field']").calendarInterval("1D"),
esb.dateHistogramAggregation('3', "d[key]['field']").calendarInterval("1D")
];
let m = null;
for(i=0;i<a.length;i++) {
if(i === 0) {
m = a[i]
} else {
m.agg(a[i])
}
}
//m = esb.dateHistogramAggregation('1', "d[key]['field']").calendarInterval('1D')
//m = m.agg(esb.dateHistogramAggregation('2', "d[key]['field']").calendarInterval("1D").agg(esb.dateHistogramAggregation('3', "d[key]['field']").calendarInterval("1D")))
esb.requestBodySearch()
.query(
esb.boolQuery()
.must(esb.matchQuery('message', 'this is a test'))
.filter(esb.termQuery('user', 'kimchy'))
.filter(esb.termQuery('user', 'herald'))
.should(esb.termQuery('user', 'johnny'))
.mustNot(esb.termQuery('user', 'cassie'))
)
.agg(esb.termsAggregation('user_terms', 'user').agg(esb.termsAggregation('user_terms', 'user').agg(esb.termsAggregation('user_terms', 'user'))))
.agg(m);
The lines commented in the code will output the result I'm expecting. What am I doing wrong?
You can turn the array into a group of sub-aggregations like so:
let a = [
esb.dateHistogramAggregation('1', "d[key]['field']").calendarInterval('1D'),
esb.dateHistogramAggregation('2', "d[key]['field']").calendarInterval("1D"),
esb.dateHistogramAggregation('3', "d[key]['field']").calendarInterval("1D")
];
const reqBody = esb.requestBodySearch()
.agg(
a[0].agg(
a[1].agg(
a[2]
)
)
);
I solved it like below. I am not sure this is right way. But someone can correct me if I am wrong.
let temp = null;
for (i = a.length - 1; i >= 0; i--) {
if (i === a.length - 1) {
temp = a[i];
} else {
temp = a[i].agg(temp)
}
}

Calculate object property values based on user id

Got an object containing a user id for each user and prices, would like to create a new object/array for each user (no duplicates) and be able to calculate the total sum of price for each user. Tried using Object.values() with map and filter but can't get it to work properly
{
"data": {
"item1": {
"price": "20",
"user": "user1"
},
"item2": {
"price": "10",
"user": "user2"
},
"item3": {
"price": "50",
"user": "user1"
}
}
}
Output something like this:
{
"users": {
"user1": {
"totalSum": "70",
},
"user2": {
"totalSum": "10",
}
}
}
I'm thinking about using map to present the "users"-data, maybe an array would be better?
Using function reduce.
Important: The attribute price is a String, this approach uses object Number to convert that value to a numeric one.
var obj = { "data": { "item1": { "price": "20", "user": "user1" }, "item2": { "price": "10", "user": "user2" }, "item3": { "price": "50", "user": "user1" } }};
var result = Object.keys(obj.data).reduce((a, k) => {
if (a.users[obj.data[k].user]) {
a.users[obj.data[k].user].totalSum += Number(obj.data[k].price);
} else {
a.users[obj.data[k].user] = {
"totalSum": Number(obj.data[k].price)
}
}
return a;
}, {
'users': {}
});
console.log(result);
.as-console-wrapper {
max-height: 100% !important; top: 0;
}
You could leverage ```reduce, more information here
code (haven't tried this)
var data = JSON.parse(mainObj).data;
var usersWithTotalExpenditure = Object.keys(data).reduce(function(result, key) {
var currentItem = data[key];
var useName = currentItem.user;
var price = Number(currentItem.price);
if (userName in result) {
result[userName].totalSum += price;
} else {
result[userName] = {
totalSum: price
};
}
return result;
}, {});
var resultObject = {
users: usersWithTotalExpenditure
}
You can use a forEach loop. This relies on Javascripts powerful OR operator, which coerces the first half of the expression to false if the current user's price is not defined (meaning it is a user the loop hasn't encountered before)
`c is your initial object's data, output is empty object`
const c = obj.data;
var output = {};
Object.keys(c).forEach((val) => {
output[c[val]["user"]] = parseInt(output[c[val]["user"]]) + parseInt(c[val]["price"]) || parseInt(c[val]["price"]);
})

Loop through JSON data in javascript

I have a php script returning JSON encoded data like below:
{
"1":
{
"from":"Vimbai Jongwe",
"msg":"wadii"
},
"2":
{
"from":"Brian Dube",
"msg":"Eh Chibaba"
}
}
So now i want to access that data using the keys from and msg to be displayed somewhere.
You can loop it like below
var data = {
"1":
{
"from":"Vimbai Jongwe",
"msg":"wadii"
},
"2":
{
"from":"Brian Dube",
"msg":"Eh Chibaba"
}
}
for(var d in data){
console.log(data[d].from +"->"+data[d].msg);
}
Try below code you can loop and print as in below code
a = {
"1":
{
"from":"Vimbai Jongwe",
"msg":"wadii"
},
"2":
{
"from":"Brian Dube",
"msg":"Eh Chibaba"
}
};
for(var i in a){
console.log(a[i].from);
console.log(a[i].msg);
}

How do I search a JSON object for a specific string value?

I want to search a JSON object to check if it contains string values stored in an array. and figure out the parent elements.
var searchVal = ['name_1a','name_2y','name_3x'];
var json = {
"location": {
"title1x": {
"1": "name_1x",
"2": "name_2x",
"3": "name_3x",
},
"title2y": {
"1": "name_1y",
"2": "name_2y",
"3": "name_3y",
},
}
"object": {
"title1a": {
"1": "name_1z",
"2": "name_2z",
"3": "name_3z",
},
"title2b": {
"1": "name_1a",
"2": "name_2a",
"3": "name_3a",
},
}
};
I want to pass the results into a function. And deal with them separate.
name_1a -> function(title2b, object)
name_2y -> function(title2y, object)
name_3x -> function(title1x, location) etc.
.
This is what I have tried so far. I can't seem to figure out how to gothrough the entire JSON object
var searchVal = ['name_1a','name_2y','name_3x'];
for (var i=0 ; i < searchVal.length ; i++){
for (var k=0 ; k < ????.length ; k++)
{
if (json.???????? == searchVal[i]) {
results.push(???????);
console.log(results);
}
}
}
with the code below you can find what you are looking for recursively:
var json = {
"location": {
"title1x": {
"1": "name_1x",
"2": "name_2x",
"3": "name_3x",
},
"title2y": {
"1": "name_1y",
"2": "name_2y",
"3": "name_3y",
},
},
"object": {
"title1a": {
"1": "name_1z",
"2": "name_2z",
"3": "name_3z",
},
"title2b": {
"1": "name_1a",
"2": "name_2a",
"3": "name_3a",
},
}
};
var searchTest = function(varToSearch, jsonData) {
for (var key in jsonData) {
if(typeof(jsonData[key]) === 'object') {
searchTest(varToSearch, jsonData[key]);
} else {
if(jsonData[key] == varToSearch) {
console.log(jsonData[key]);
}
}
}
}
searchTest('name_1a', json);
Reference:
get data from dynamic key value in json
get value from json with dynamic key
https://trinitytuts.com/tips/get-dynamic-keys-from-json-data/
How do I enumerate the properties of a JavaScript object?
Check if a value is an object in JavaScript
What about something like this:
var json = {
"location": {
"title1x": {
"1": "name_1x",
"2": "name_2x",
"3": "name_3x",
},
"title2y": {
"1": "name_1y",
"2": "name_2y",
"3": "name_3y",
},
},
"object": {
"title1a": {
"1": "name_1z",
"2": "name_2z",
"3": "name_3z",
},
"title2b": {
"1": "name_1a",
"2": "name_2a",
"3": "name_3a",
"foo": [{
"x": "aaa",
"y": "bbb",
"z": {
"k": "name_3y"
}
}, {
"x": "aaa",
"y": "bbb",
"z": {
"k": "name_3y",
"bar": [{
"op": "test",
"fooAgain": {
"x": "name_3y"
}
}]
}
}]
},
}
};
function search(what, where) {
var results = [];
var parentStack = [];
var searchR = function(what, where) {
if (typeof where == "object") {
parentStack.push(where);
for (key in where) {
searchR(what, where[key]);
};
parentStack.pop();
} else {
// here comes your search
if (what === where) {
results.push({
parent: parentStack[parentStack.length - 1],
value: where
});
}
}
}
searchR(what, where);
return results;
}
search("name_3y", json).forEach(function(value, key) {
var out = "parent: \n";
for (key in value.parent) {
out += " key: " + key + " - value: " + value.parent[key] + "\n";
}
out += "\nvalue: " + value.value;
alert(out);
});
The search function will search for a value that is exactly equal inside a json object. You can use it to search for each element of an array for example, just adjust the code. A stack was necessary, since we need to keep track of the parents. I modified your json to insert more levels. The values of the results are objects with two attributes. I think that with this you can do what you need. You can, of course, modify my code to use regular expressions intead of strings in your search. It would be more powerfull.
var searchVal = ['name_1a','name_2y','name_3x'];
var json = {
"location": {
"title1x": {
"1": "name_1x",
"2": "name_2x",
"3": "name_3x",
},
"title2y": {
"1": "name_1y",
"2": "name_2y",
"3": "name_3y",
}
},
"object": {
"title1a": {
"1": "name_1z",
"2": "name_2z",
"3": "name_3z",
},
"title2b": {
"1": "name_1a",
"2": "name_2a",
"3": "name_3a",
}
}
};
var getTitle=function(json,val){
for (var key in json) {
var titles= json[key];
for (var tit in titles) {
var names=titles[tit];
for (var name in names) {
var string=names[name];
if(string===val)
return tit;
}
}
}
}
searchVal.forEach(function(valToSearch){
console.log(getTitle(json,valToSearch));
});

Loop through all documents in a nested function

I started using Couchbase for a new project of mine and I hope you can help me solve a problem.
I have two types of documents in my bucket. For example:
{
"id": "A1",
"name": "Name of A",
"type": "A"
}
and
{
"id": "B1",
"name": "Name of B",
"type": "B",
"parentIDs": ["A1", "A4", "A5"]
}
I want to create a view with the following result:
{
"id": "A1",
"name": "Name of A",
"type": "A",
"children": [
{JSON document of child 1},
{JSON document of child 2},
{JSON document of child 3}
]
}
I started to write a function and a nested one, which should iterate through all documents but I must surrender... Can you help me?
function (doc, meta)
{
if(doc.type == "A")
{
emit(doc, GetAllSites(doc));
}
function GetAllSites(doc)
{
var sites = [];
for(var i = 0; i < doc.length; i++)
{
sites.push(doc.id);
}
return sites;
}
}
Thanks
-----------------UPDATE-----------------
I solved my problem this way:
// map function
function (doc, meta)
{
emit(meta.id, doc);
}
// reduce function
function (key, values, rereduce)
{
var result = [];
for(var i = 0; i < values.length; i++)
{
var val1 = values[i];
if(val1.type != "A")
continue;
val1.childrenIDs = [];
for(var j = 0; j < values.length; j++)
{
var val2 = values[j];
switch(val2.type)
{
case "B":
if(contains(val2.parentIDs, val1.id))
val1.childrenIDs.push(val2);
break;
default:
break;
}
}
result.push(val1);
}
return result;
function contains(a, obj) {
var i = a.length;
while (i--) {
if (a[i] === obj) {
return true;
}
}
return false;
}
}
May be no "blue-print" solution but it works and I'll optimize it later. :-)
You can't use nested functions, in you case I'll recommend to use reduce function after map function.
So you need paste you GetAllSites function code to reduce
And don't forget to realize rereduse logic

Categories