I moved this question reported as issue 94 to the discussion group:
json data :
{
"someone1":{
{“name”:["value":"tom"] }
{“live”:["value":"USA"] }
{“like”:["value":"tom"] }
},
"someone2":{“name”:["value":"bob"] }
}
In this case , I just want get this result
{"someone1":{ {“name”:["value":"tom"] } } }
I want to know how to write the jaql pipes.
---------------------------------------------------------------------------------------
Response:
Your data structure isn't valid JSON; it has name-value pairs as
elements of an array inside [], and appears to have an array inside of
a record {} but without commas. Here is a structure that hopefully
matches your intent. I'm writing jaql here, which is where the
variable assignment comes from:
x = { someone1: [ { name: { value: "tom" }},
{ live: { value: "USA" }},
{ like: { value: "tom" }} ],
someone2: [ { name: { value: "bob" }} ]
};
Jaql doesn't have any update syntax yet, so you usually have to
rebuild your structure. Here's an example that produces your desired
result:
{ someone1: x.someone1 -> filter exists($.name) };
The result is:
{ "someone1": [ { "name": { "value": "tom" } } ] }
If you also wanted to remove the array, the singleton() function takes
an array verifies that it has at most one element and returns that
element without the array (or null if there is not element):
{ someone1: x.someone1 -> filter exists($.name) -> singleton() };
Now the array is removed from the result:
{ "someone1": { "name": { "value": "tom" } } }
Jaql does have a projection syntax that lets you project a JSON
structure. This example projects just the "someone1" field and every
"name" field in the nested array:
x{.someone1[*]{.name}}
However, it doesn't work that well for your case because it leaves
empty records for the "live" and "like" records:
{ "someone1": [ { "name": { "value": "tom" } }, {}, {} ] }
We will probably add predicates to the projections down the road to
solve this.
There might be a better way to model your data. It looks like you
have data that is converted from XML. XML data tends to mix repeating
elements in the same list (of children) with other fields. I'm
assuming you are representing a list of people. People have a name, a
place they live, and may like many other people. A typical XML
representation would be:
<people>
<person id='1'>
<name>tom</name>
<live>USA</live>
</person>
<person id='2'>
<name>bob</name>
<live>Spain</live>
<likes>tom</likes>
<likes>jerry</likes>
</person>
</person>
A typical JSON representation would match a the usual programming
representation: repeating elements are grouped into an array (the
"likes" array below):
people = [
{ id: 1, name: "tom", live: "USA" },
{ id: 2, name: "bob", live: "Spain", likes: ["tom","jerry"] }
];
Now your question above becomes really easy:
people[0].name;
This produces simply: "tom"
If you don't know the exact index, you can search for it, say by using
the "id":
people -> filter $.id == 1 -> transform $.name;
A filter can return many results, depending on the predicate:
people -> filter $.live == "USA" -> transform $.name;
For our example, both of these produce: [ "tom" ]
If you want to guarantee a single result and remove the array:
people -> filter $.id == 1 -> transform $.name -> singleton();
This produces simply: "tom"
If you want to extract multiple fields, use a transform:
people -> filter $.live == "USA" -> transform { $.name, $.live };
This produces: [ { "name": "tom", "live": "USA" } ]
Just for kicks, I decided to write an example that works with the
nested list:
// Build the list of users that someone might like
// p states they like q
// q hasn't stated that they like p
// return each q with a nested list of all p
join p in (people -> expand unroll $.likes),
q in people
where p.likes ==
q.name
into { p, q } // p likes q
-> filter not( $.
p.name in firstNonNull($.q.likes,[]) ) // q
doesn't like p yet
-> transform { $.
q.id, $.
q.name, mightlike: { $.
p.id, $.
p.name } }
-> group by id = $.id // nest the list of users that like a user
into { id, name: any($[*].name), mightlike: $[*].mightlike }
;
Produces:
[ { "id": 1, "name": "tom", "mightlike": [ { "id": 2, "name":
"bob" } ] } ]