Join on multiple ids from the same table - javascript

I'm trying to join a two tables (versus and words) on multiple ids. I don't really know how to explain it, so I'm just going to show what I mean.
An excerpt from the versus-table:
{
"date": 1427675857789,
"hero": "7b88a237-c288-48f1-bf45-2dcd9f812b54",
"id": "017fe06a-e37d-4f23-92a3-bc52b38de4d7",
"nemesis": "e87a6252-6d08-4c5a-b057-2718e8c07d93",
"points": {
"hero": 58659,
"nemesis": 3021
}
}
Excerpt from the words-table:
{
"id": "7b88a237-c288-48f1-bf45-2dcd9f812b54" ,
"word": "i"
},
{
"id": "e87a6252-6d08-4c5a-b057-2718e8c07d93" ,
"word": "the"
}
I'd like to join the two tables so get something like this:
{
"date": 1427675857789,
"hero": "i",
"nemesis": "the",
"points": {
"hero": 58659,
"nemesis": 3021
}
}
This is what I have so far: r.table("versus").eqJoin("hero", r.table("words")).zip(), which gets me this:
{
"date": 1427675857789 ,
"hero": "7b88a237-c288-48f1-bf45-2dcd9f812b54" ,
"id": "7b88a237-c288-48f1-bf45-2dcd9f812b54" ,
"nemesis": "e87a6252-6d08-4c5a-b057-2718e8c07d93" ,
"points": {
"hero": 60507 ,
"nemesis": 3504
} ,
"word": "i"
}
I'm a little puzzled about how I can join it on the hero-row as well as nemesis-row.
Though I'd be happy with any result that shows most of the things from the versus-table (Doesn't matter if id is there) and two the two words which corresponds to the hero and nemesis id.
EDIT: I've figured something out, but now I'm only able to get the first document, which kind of defeats the purpose of what I'm trying to do... Here's what I got: r.table("versus").eqJoin("hero", r.table("words")).zip().map(r.row.merge({hero: r.row("word")})).eqJoin("nemesis", r.table("words")).zip().map(r.row.merge({nemesis: r.row("word")})).without(["word", "id"])

Well, I did it...finally!
If someone's interested, this is what my new ReQL looks like:
r.table("versus").concatMap(function(v){
return r.table("words").getAll(v("hero"), {index: "id"}).map(function(w){
return r.branch(
v("hero").eq(w("id")),
v.merge({hero: w("word")}),
v
)
})
}).concatMap(function(v){
return r.table("words").getAll(v("nemesis"), {index: "id"}).map(function(w){
return r.branch(
v("nemesis").eq(w("id")),
v.merge({nemesis: w("word")}),
v
)
})
}).without("id")

Related

elasticsearch autosuggest returning tricky JSON

I'm running a node.js server that sends queries to an elasticsearch instance. Here is an example of the JSON returned by the query:
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 9290,
"max_score": 0,
"hits": []
},
"suggest": {
"postSuggest": [
{
"text": "a",
"offset": 0,
"length": 1,
"options": [
{
"text": "Academic Librarian",
"score": 2
},
{
"text": "Able Seamen",
"score": 1
},
{
"text": "Academic Dean",
"score": 1
},
{
"text": "Academic Deans-Registrar",
"score": 1
},
{
"text": "Accessory Designer",
"score": 1
}
]
}
]
}
}
I need to create an array containing each job title as a string. I've run into this weird behavior that I can't figure out. Whenever I try to pull values out of the JSON, I can't go below options or everything comes back as undefined.
For example:
arr.push(results.suggest.postSuggest) will push just what you'd expect: all the stuff inside postSuggest.
arr.push(results.suggest.postSuggest.options) will come up as undefined even though I can see it when I run it without .options. This is also true for anything below .options.
I think it may be because .options is some sort of built-in function that acts on variables, so instead of seeing options as JSON and is instead trying to run a function on results.suggest.postSuggest
arr.push(results.suggest.postSuggest.options)
postSuggest is an array of object.options inside postSuggest is also array of object. So first you need to get postSuggest by postSuggest[0] and then
postSuggest[0].options to get array of options
This below snippet can be usefule
var myObj = {..}
// used jquery just to demonstrate postSuggest is an Array
console.log($.isArray(myObj.suggest.postSuggest)) //return true
var getPostSuggest =myObj.suggest.postSuggest //Array of object
var getOptions = getPostSuggest[0].options; // 0 since it contain only one element
console.log(getOptions.length) ; // 5 , contain 5 objects
getOptions.forEach(function(item){
document.write("<pre>Score is "+ item.score + " Text</pre>")
})
Jsfiddle

Find JSON nested nodes using multiple string values

I have a screen that needs to calculate prices based on two different parameters, primary (activity in example) and children (ticketType in example)
Previously this was done hackishly, so i decided the best option would be to store the prices in a JSON object populated at runtime, and based on clicks & change events
So i have this json format I formulated, please note you can change this as well, not set in stone
{
"activities": [{
"activitycode": "TK",
"desc": "Tickets",
"ticketTypes": [{
"ticketcode": "G",
"baseprice": 79
}, {
"ticketcode": "P",
"baseprice": 109
}]
}, {
"activitycode": "PK",
"desc": "Parking",
"ticketTypes": [{
"ticketcode": "BK",
"baseprice": 65
}, {
"ticketcode": "ESC-I",
"baseprice": 40
}]
}], //end activities
"handlingPercent": "0.03",
"shipping": "15"
}
So, I tried traverse the JSON object for the correct price, like this
pricing.activities.activitycode['TK'].ticketTypes.ticketcode['G'].baseprice
but this doesnt work, because I havent specified which numerical node to go to yet before supplying my values
Once i did that, the following works
pricing.activities[0].ticketTypes[0].baseprice
But what i would like to accomplish is supplying string/text values, traverse parent nodes, then child nodes, and find the value
I suppose i could do an $.each iteration like this, but i wanted to know what the experts thought first, if this is indeed the best way to go about things
$.each(pricing.activities, function(arrayID, activityData) {
if(activityData.activitycode=="TK")
$.each(activityData.ticketTypes, function(ticketTypeID, typeData) {
if(typeData.ticketcode=="G")
alert(typeData.baseprice);
});
});
Before talking about the code, let's talk about your JSON data.
First, I reformatted the data so I could follow the structure more easily:
{
"activities": [
{
"activitycode": "TK",
"desc": "Tickets",
"ticketTypes": [
{ "ticketcode": "G", "baseprice": 79 },
{ "ticketcode": "P", "baseprice": 109 }
]
},
{
"activitycode": "PK",
"desc": "Parking",
"ticketTypes": [
{ "ticketcode": "BK", "baseprice": 65 },
{ "ticketcode": "ESC-I", "baseprice": 40 }
]
}
],
"handlingPercent": "0.03",
"shipping": "15"
}
Now that the structure is clear, here is the question: You have an activities array, and inside each of the elements of that array there is a ticketTypes array.
Does the order of items in these arrays matter? i.e. are they used to generate a display list that must be in the correct order?
And, how do you need to access these arrays? Do you primarily loop through them and do something with all the elements? Or do you use them to look up individual elements given a known activitycode and ticketcode - which is what the nested $.each loops at the end of your question end up doing?
Depending on the answers to these questions, you may be better served with a different kind of structure. Perhaps like this:
{
"activities": {
"TK": {
"desc": "Tickets",
"ticketTypes": {
"G": { "baseprice": 79 },
"P": { "baseprice": 109 }
}
},
"PK": {
"desc": "Parking",
"ticketTypes": {
"BK": { "baseprice": 65 },
"ESC-I": { "baseprice": 40 }
}
}
},
"handlingPercent": "0.03",
"shipping": "15"
}
Because now this code (I cleaned up the indentation here too):
$.each( pricing.activities, function( arrayID, activityData ) {
if( activityData.activitycode=="TK" ) {
$.each( activityData.ticketTypes, function( ticketTypeID, typeData ) {
if( typeData.ticketcode=="G" )
alert( typeData.baseprice );
});
}
});
can be replaced with:
alert( pricing.activities.TK.ticketTypes.G.baseprice );
and other similar code that you write will also be simpler. About the only thing you lose this way is the guarantee of ordering of the activities and ticketTypes: arrays have a guaranteed order, objects do not.
Have you tried $.grep()?
var test = $.grep(pricing.activities, function(e){ return e.activitycode == 'TK'; });
var test2 = $.grep(test[0].ticketTypes, function(e){ return e.ticketcode == "G";});
console.log(test2[0].baseprice);
Fiddle Here. jQuery API Documentation on $.grep() here
Example from this question
I wouldn't say it's better than $.each(), but it's another method, if you're into that sort of thing.

Javascript looping through elements and adding to table

I'm having trouble finding a solution that will help me loop through a bunch of elements and putting the chosen values into a table. I've been able to withdraw some values but the method isn't dynamic.
Here is an example:
var Table = {
"credit": {
"link": "site link",
"logoUrl": "logo url",
"message": "message"
},
"groups": [
{
"labels": [
{
"name": "Western Conference",
"type": "conference"
},
{
"name": "Central Division",
"type": "division"
}
],
"standings": [
{
"stats": [
{
"name": "gp",
"value": 20
},
{
"name": "w",
"value": 17
},
{
"name": "l",
"value": 0
},
{
"name": "gf",
"value": 64
},
{
"name": "ga",
"value": 37
},
{
"name": "gd",
"value": 27
},
{
"name": "pts",
"value": 37
}
],
"team": {
"id": 12345,
"link": "team link",
"name": "team name",
"shortName": "team"
}
},
This is the structure of the elements. So far I've used this:
document.getElementById("sGamesPlayed").innerHTML=Table.groups[0].standings[0].stats[0].value;
to withdraw values. However there are more teams, stats and divisions so I would need some kind of loop to go through the elements and put the into a dynamic table.
I would consider you to look at http://underscorejs.org/.
it provides a bunch of utility functions that could help you,
for example, _.each() helps you loop through JSON properties.
for the sample objects you've given (after completing the missing brackets at the end),
_.each(Table.groups[0].standings[0].stats, function(stats){
console.log(stats['name']+","+stats['value'])
})
gives me:
gp,20
w,17
l,0
gf,64
ga,37
gd,27
pts,37
how it works is that you provide the object you want as the first argument and the function that you give as the second argument will be called with each element of the first argument (Assuming it is a list).
I would also urge you to look at underscore templating that you can use to render your table where i put the console.log :
http://net.tutsplus.com/tutorials/javascript-ajax/getting-cozy-with-underscore-js/
http://scriptble.com/2011/01/28/underscore-js-templates/
I guess your question is about filtering the values of the array standings. In order to do that you can use the jQuery grep function (if you want to use jQuery).
For example you can write:
var arr = $.grep(Table.groups[0].standings[0].stats, function(d){return d.value>25})
Which will give
arr = [{"name": "gf","value": 64}, {"name": "ga", "value": 37},{"name": "gd", "value": 27},{"name": "pts", "value": 37}]
If this is not what you meant, can you please create a jsFiddle with a sample of what you want?
Depending on what you want to do with the results, you can go over the object using a scheme like:
var groups, standings, stats, value;
groups = Table.groups;
// Do stuff with groups
for (var i=0, iLen=groups.length; i<iLen; i++) {
standings = groups[i].standings;
// Do stuff with standings
for (var j=0, jLen=standings.length; j<jLen; j++) {
stats = standings[j];
// Do stuff with stats
for (var k=0, kLen=stats.length; k<kLen; k++) {
value = stats[k].value;
// Do stuff with value
}
}
}
Of course I have no idea what the data is for, what the overall structure is or how you want to present it. But if you have deeply nested data, all you can do is dig into it. You might be able to write a recursive function, but it might also become very difficult to maintain if the data structure is complex.

JavaScript -- split off one branch of a hierarchical array or JSON object

I have a JSON object that is a nested array that is of the following form:
{
"name": "Math",
"children": [
{
"name": "Trigonometry",
"children": [
{
"name": "Right Triangles and an Introduction to Trigonometry",
"children": [
{
"name": "The Pythagorean Theorem",
"children": [
{
"name": "The Pythagorean Theorem",
"size": 30
},
{
"name": "Pythagorean Triples",
"size": 52
},
{
"name": "Converse of the Pythagorean Theorem",
"size": 13
}
]
}
]
}
]
},
{
"name": "Algebra",
"children": [
{
"name": "Equations and Functions",
"children": [
{
"name": "Variable Expressions",
"children": [
{
"name": "Evaluate Algebraic Expressions",
"size": 26
}
]
}
]
}
]
}
]
}
The full array is actually much larger and can be seen here. I'm using it to build interactive graphs and charts using D3.js (or perhaps other libraries). Because it's so large, I'd like to be able to split the array by branch. In other words, to carve out particular branches of the array.
For instance, is there a way to just pull out the node "Trigonometry" and all its children? Or "Algebra" and all its children? Then "Trigonometry" or "Algebra" would become the new root or parent node.
There is no built-in way to do something like this, although the comment about a JSON query language might give you the right work-around.
Really, the problem is that you have structured your data in a way that makes it very hard to use. If instead of
{
name: "key",
children: [...]
}
you just did
{
"key": [...]
}
then you could simply do myObject["key"] to get the array you want.
For example:
var math = {
"Trigonometry": {
"Right Triangles and an Introduction to Trigonometry": {
"The Pythagorean Theorem": {
"The Pythagorean Theorem": 30,
"Pythagorean Triples": 52,
"Converse of the Pythagorean Theorem": 13
}
}
},
"Algebra": {
"Equations and Functions": {
"Variable Expressions": {
"Evaluate Algebraic Expressions": 26
}
}
}
};
var trigonometry = math["Trigonometry"];
var expressionsAndFunctions = math["Algebra"]["Expressions and Functions"];
As a bonus, that's much shorter!
Array's splice function should do it. What that will do is remove the element at a given index and return it.
If you just want a shortcut to a specific branch, couldn't you also just use
var trig = tree['trigonometry'];
to get there. This wouldn't change the original object, buy will give you a simpler way to access nodes deep inside.

How to retrieve value from json output?

I am new to json. I have json output that looks like this
[
{
"employees": {
"education": "BE\/B.Tech"
},
"0": {
"count": "1"
}
},
{
"employees": {
"education": "MBA"
},
"0": {
"count": "3"
}
}
]
I want to retrieve the employee's education and the count. I have tried but i am not able to retrieve the values.
I appreciate any help.
Thanks.
Assuming your JSON string is in a variable $json, it goes like this:
var employees_list = JSON.parse($json);
Then you can access the information via:
employees_list[0].employees.education // gives you "BE\/B.Tech"
// and
employees_list[0]["0"].count // gives you 1.
You can also loop over the array and access all the different education this way.
Update:
To better demonstrate which expression accesses which information:
[ // employees_list
{ // employees_list[0]
"employees": { // employees_list[0].employees
"education": "BE\/B.Tech" // employees_list[0].employees.education
},
"0": { // employees_list[0]["0"]
"count": "1" // employees_list[0]["0"].count
}
},
{ // employees_list[1]
"employees": { // employees_list[1].employees
"education": "MBA" // employees_list[1].employees.education
},
"0": { // employees_list[1]["0"]
"count": "3" // employees_list[1]["0"].count
}
}
]
Generally employees_list[0].employees is the same as employees_list[0]["employees"] but this does not work for numbers, because properties and variables are not allowed to start with numbers. So you can only use employees_list[0].["0"] and not employees_list[0].0.
The structure of your JSON string looks a bit strange though. You should consider to structure it differently if you can.
For example:
[
{
"education": "BE\/B.Tech",
"count": "1"
},
{
"education": "MBA"
"count": "3"
}
]
The "0" key in your original JSON string seems to serve no purpose and just complicates the access.

Categories

Resources