JSON Path - How to find the root elements based on child elements? - json

I have a JSON object, and I'm trying to find the root elements under it. Can someone please help me to figure this out?
{
"store" : {
"10162021" : {
"id" : 812340,
"properties" : {
"server" : "server1.example.org",
"serverip" : "",
}
},
"10162022" : {
"properties" : {
"serverip" : "127.0.0.1",
"server" : "server2.example.org",
},
"id" : 859480
}
}
}
I need to extract the root elements 10162022, 10162021 based on the server name.
I have tried to use syntax like below, but it was not successful
$..*..[?(#.server == server2.example.org)]
I will appreciate any suggestions.

It's not clear whether you want to return the keys "10162022", etc, or the values, like:
{
"properties" : {
"serverip" : "127.0.0.1",
"server" : "server2.example.org"
},
"id" : 859480
}
If you want to return values, the following JSONPath should work:
$.store[?( #.properties.server=="server2.example.org" )]
If you want to return keys, I'm not entirely sure that's possible. JSONPath isn't really designed to find keys, but values.
If you need the keys, I would suggest pre-processing the structure to stash the keys into objects as values, like this:
{
"store" : {
"10162021" : {
"__key" : "10162021",
"id" : 812340,
"properties" : {
"server" : "server1.example.org",
"serverip" : ""
}
},
"10162022" : {
"__key" : "10162022",
"properties" : {
"serverip" : "127.0.0.1",
"server" : "server2.example.org"
},
"id" : 859480
}
}
}
Then use this JSONPath:
$.store[?( #.properties.server=="server2.example.org" )].__key

Related

How to acess an entity under _links in Angular from Spring Data REST?

I encountered a problem which is very challenging to my Angular level. Could you give a help please?
In Spring Data REST the entity Worker has a #OneToMany bidirectional relationship with the entity TempworkEvent, shown below under _links. I would like to access TempworkEvent objects and their attributes through this relationship.
{
"id" : 3,
"name" : "Nadja Miller",
"profession" : "Experte/in Anästhesiepflege",
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/workers/3"
},
"worker" : {
"href" : "http://localhost:8080/api/workers/3"
},
"tempworks" : {
"href" : "http://localhost:8080/api/workers/3/tempworks"
},
"tempworkEvents" : {
"href" : "http://localhost:8080/api/workers/3/tempworkEvents"
}
}
In Angular the Worker entity successfully:
getWorkers(): Observable<Worker[]> {
return this.httpClient.get<GetResponseWorkers>(this.workersUrl).pipe(
map(response => response._embedded.workers)
);
}
(...)
interface GetResponseWorkers {
_embedded: {
workers: Worker[];
}
}
The challenge is how to access the Worker's tempworkEvents object and its attributes through _links:
"tempworkEvents" : {
"href" : "http://localhost:8080/api/workers/3/tempworkEvents"
}
One of:
Make an additional network request to get the TempworkEvents
Don't have a TempworkEvent JPA repository, and Spring Data Rest will include the tempworkEvents data in the workers response
or, use a Projection, like:
in entities/projections/MyWorkerProjection.java:
#Projection(name="foo", types={Worker.class})
public interface MyWorkerProjection {
Long getId();
String getName();
String getProfession();
List<TempworkEvent> getTempworkEvents();
}
Then call http://localhost:8080/api/workers/3?projection=foo
If you want to have "auto" projections, see: Spring Data REST: projection representation of single resource
You may want to create another interface for TempworkEvent, if you want to project its data as well as its links
let obj = {
"id" : 3,
"name" : "Nadja Miller",
"profession" : "Experte/in Anästhesiepflege",
"_links" : {
"self" : {
"href" : "http://localhost:8080/api/workers/3"
},
"worker" : {
"href" : "http://localhost:8080/api/workers/3"
},
"tempworks" : {
"href" : "http://localhost:8080/api/workers/3/tempworks"
},
"tempworkEvents" : {
"href" : "http://localhost:8080/api/workers/3/tempworkEvents"
}
}
}
console.log('tempworkEvents',obj._links.tempworkEvents);
You can access the object like above.

Delete all but one key-value pair from JSON

I have this:
{
"service" : {
"category" : "managed-object",
"resource" : "attribute",
"action" : "delete",
"options" : {
"uuid" : "#VALUE",
"attributes" : {
"name" : {
"value" : "#VALUE"
},
"contactInfo" : "",
"activationDate" : "",
"deactivationDate" : "",
"protectStopDate" : "",
"processStartDate" : ""
}
}
}
}
I need this:
{
"service" : {
"category" : "managed-object",
"resource" : "attribute",
"action" : "delete",
"options" : {
"uuid" : "#VALUE",
"attributes" : {
"name" : {
"value" : "#VALUE"
}
}
}
}
}
Previously I had a similar problem that was a little bit more complicated, and I received this amazingly simple answer from someone here:
.service.options |= (del(.max, .objectGroupMember) | .attributes|={name})
That jq command works even here, but of course (.max, .objectGroupMember) does not make sense because it does not exist.
How can I achieve my desired result?
A different take on the problem:
walk(if type=="object" then with_entries(select(.value!="")) else . end)
I found it in Weeble's answer to my earlier question:
'.service.options.attributes |= {name}'

How to use .indexOn for dynamic keys in firebase?

I have a DB in Firebase with this structure:
{
"chats" : {
"-L-hPbTK51XFwjNPjz3X" : {
"lastMessage" : "Hello!",
"timestamp" : 1512590440336,
"title" : "chat 1",
"users" : {
"Ol0XhKBksFcrYmF4MzS3vbODvT83" : true
}
}
},
"messages" : {
"-L-hPbTK51XFwjNPjz3X" : {
"-L-szWDIKX2SQl4YZFw9" : {
"message" : "Hello!",
"timestamp" : 1512784663447,
"userId" : "Ol0XhKBksFcrYmF4MzS3vbODvT83"
}
}
},
"users" : {
"Ol0XhKBksFcrYmF4MzS3vbODvT83" : {
"chats" : {
"-L-hPbTK51XFwjNPjz3X" : true
},
"email" : "mm#gmail.com",
"name" : "mm"
}
}
}
My code:
Database.database().reference().child("chats")
.queryOrdered(‌​byChild: "users/(userId)").queryEqual(toValue: true).observe(.value, with: { snapshot in .... }
When I try to get chat members or user chats, It shows this warnings:
Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding ".indexOn": "chats/-L-hPbTK51XFwjNPjz3X" at /users to your security rules for better performance.
Using an unspecified index. Your data will be downloaded and filtered on the client. Consider adding ".indexOn": "users/Ol0XhKBksFcrYmF4MzS3vbODvT83" at /chats to your security rules for better performance.
I found lots of solutions but anything works fine for me. I want to define IndexOn rules in my DB, Can you help me?

Elasticsearch update mapping using json

I want to change the type of a field from 'string' to 'date' (format: 'epoch_second' to be specific). Since there is no way to update the mappings of an existing index, I need to make a new index for which I mostly want to use the mapping from my existing index. Here is what I am using:
curl -XGET 'http://localhost:9200/sam/saga/_mapping?pretty' >saga.json
to dump the mapping of the current index into a json file, the content of which is this:
{
"sam" : {
"mappings" : {
"saga" : {
"properties" : {
"name" : {
"type" : "long"
}
}
}
}
}
}
then I replace
"name" : {
"type" : "long"
}
with
"name" : {
"type" : "date"
}
and save the new file as saga2.json. then run this
curl -XPUT 'http://localhost:9200/sam/_mapping/saga2' -d #saga2.json
However, when I check the mapping of the new index, all types have changed to "string" now.
I even have this problem using the Elasticsearch's example.
Does anyone know what is wrong?
You need to make one more change in your saga2.json file, namely the mapping type name saga -> saga2 (Now you probably need to rename it all to saga3
{
"sam" : {
"mappings" : {
"saga2" : { <--- here
"properties" : {
"name" : {
"type" : "date" <--- and here
}
}
}
}
}
}
Then only you can run this:
curl -XPUT 'http://localhost:9200/sam/_mapping/saga2' -d #saga2.json

How to create an index with integer fields in Elasticsearch for the JSON file of format?

I am trying to create an index in Elasticsearch for the JSON file of format:
{ "index" : { "_index" : "entity", "_type" : "type1", "_id" : "0" } }
{ "eid":"guid of Event autogenerated", "entityInfo": { "entityType":"qualityevent", "defaultLocale":"en-US" }, "systemInfo": { "tenantId":"67" }, "attributesInfo" : { "jobId":"21", "matchStatus": "new" } }
{ "index" : { "_index" : "entity", "_type" : "type1", "_id" : "1" } }
{ "eid":"guid of Event autogenerated", "entityInfo": { "entityType":"qualityevent", "defaultLocale":"en-US" }, "systemInfo": { "tenantId":"67" }, "attributesInfo" : { "jobId":"20", "matchStatus": "existing" } }
I want the fields jobId and tenantId to be integers.
I am giving the following mapping in curl command:
curl -XPUT http://localhost:9200/entity -d '
{
"mappings": {
"entityInfo":
{
"properties" : {
"entityType" : { "type":"string","index" : "not_analyzed"},
"defaultLocale":{ "type":"string","index" : "not_analyzed"}
}
},
"systemInfo":
{
"properties" : {
"tenantId": { "type" : "integer" }
}
},
"attributesInfo" :
{
"properties" : {
"jobId": { "type" : "integer" },
"matchStatus": { "type":"string","index" : "not_analyzed"}
}
}
}
}
';
This does not give me an error. However, it creates new empty fields jobId and tenantId as integers and it keeps the existing data into attributesInfo.jobId as string. Same is the case with systemInfo.tenantId. I want to use these two fields in Kibana for visualization. I currently cannot use them as they are empty.
I am new to Kibana and Elasticsearch so I am not sure if the mapping is correct.
I have tried couple of other mappings as well but they give errors. Above mapping does not give error.
This is how Discover Tab on Kibana looks like: 1
Please let me know where I am going wrong.
I tried as you mentioned but it didn't help. What I realised after a lot of trial and error that my mapping was incorrect. I finally wrote the correct mapping and now it works correctly. Jobid and TenantId are recognised as numbers by Kibana. I am new to JSON, kibana, Bulk, Elastic so it took time to understand how mapping works.