Perl: Combine two JSONs - json

I am looking for help/guidance to combine multiple JSON into 1 JSON based on a node in PERL. For example here are the two JSON content that I want to combine.
JSON #1:
{
"title": "All",
"lastModified": "2017-04-11T00:00:00.000+0000",
"users": [{
"name": "Alpha One",
"title": "Security Chief",
"locations": [{"id": "730WLCS"}, {"id": "943MCS"}]
},
{
"name": "Alpha Two",
"title": "Security Manager"
}
]
}
JSON #2:
{
"title": "All",
"lastModified": "2017-04-11T00:00:00.000+0000",
"users": [{
"name": "Beta One",
"title": "Architect",
"locations": [{"id": "730WLCS"}]
}
]
}
RESULT JSON :
{
"title": "All",
"lastModified": "2017-04-11T00:00:00.000+0000",
"users": [{
"name": "Alpha One",
"title": "Security Chief",
"locations": [{"id": "730WLCS"}, {"id": "943MCS"}]
},
{
"name": "Alpha Two",
"title": "Security Manager"
},
{
"name": "Beta One",
"title": "Architect",
"locations": [{"id": "730WLCS"}]
}
]
}
Basically, I want to combine only the "users" node.
I tried to get the node using from_json and tried to push into an array, but it is not working.
Here is the code that I tried:
my $json_obj1 = from_json($json_txt1, {utf8 => 1});
my $json_obj2 = from_json($json_txt2, {utf8 => 1});
push(#myJSON, #{$json_obj1->{'users'}});
push(#myJSON, #{$json_obj2->{'users'}});
Any help is much appreciated.
Thank you.

my $json_obj1 = decode_json($json_txt1); # Same as from_json($json_txt1, {utf8 => 1})
my $json_obj2 = decode_json($json_txt2);
push #{ $json_obj2->{users} }, #{ $json_obj1->{users} };
If you want to remove duplicates , keeping the newer records (assuming $json_obj1 is the older state), you can use the following:
my %seen;
#{ $json_obj2->{users} } =
grep !$seen{$_->{name}}++,
#{ $json_obj2->{users} },
#{ $json_obj1->{users} };

Related

Parsing Git Json with Regular Express

I am taking a Github json file and parsing it with Java's regular expression library JsonPath. I am having a problem parsing arrays that do not have labels.
I need to send a email every time a particular file is changed in our repository.
Here is the Git Json:
{
"trigger": "push",
"payload": {
"type": "GitPush",
"before": "xxxxxxxx",
"after": "yyyyyyyy",
"branch": "branch-name",
"ref": "refs/heads/branch-name",
"repository": {
"id": 42,
"name": "repo",
"title": "repo",
"type": "GitRepository"
},
"beanstalk_user": {
"type": "Owner",
"id": 42,
"login": "username",
"email": "user#example.org",
"name": "Name Surname"
},
"commits": [
{
"type": "GitCommit",
"id": "ffffffff",
"message": "Important changes.",
"branch": "branch-name",
"author": {
"name": "Name Surname",
"email": "user#example.org"
},
"beanstalk_user": {
"type": "Owner",
"id": 42,
"login": "username",
"email": "user#example.org",
"name": "Name Surname"
},
"changed_files": {
"added": [
"NEWFILE",
],
"deleted": [
"Gemfile",
"NEWFILE"
],
"modified": [
"README.md",
"NEWFILE"
],
"copied": [
]
},
"changeset_url": "https://subdomain.github.com/repository-name/changesets/ffffffff",
"committed_at": "2014/08/18 13:30:29 +0000",
"parents": [
"afafafaf"
]
}
]
}
}
This is the expression I am using: to get the commits
$..changed_files
This return the whole changed files part but I can not explicitly choose the name "NEWFILE"
I tried
$..changed_files.*[?(#.added == "NEWFILE")]
$..changed_files.*[?(#.*== "NEWFILE")]
It just returns a empty array.
I just want it to return Newfile and what type of change. Any Ideas?
You can use the following JsonPath to retrieve the commits which list "NEWFILE" as an added file :
$.payload.commits[?(#.changed_files.added.indexOf("NEWFILE") != -1)]

lodash sort an array of objects by a property which has an array of objects

I have a an object. I am able to sort the items by using lodash's _.orderBy().
However, in one of the scenario I have to sort by subject, which is an array of objects. Items inside the subject array are already sorted based on the name.
As subject is an array of the objects, I need to consider the first item for sorting.
[
{
"id": "1",
"name": "peter",
"subject": [
{
"id": "1",
"name": "maths"
},
{
"id": "2",
"name": "social"
}
]
},
{
"id": "2",
"name": "david",
"subject": [
{
"id": "2",
"name": "physics"
},
{
"id": "3",
"name": "science"
}
]
},
{
"id": "3",
"name": "Justin",
"subject": [
]
}
]
You can use _.get() to extract the name (or id) of the 1st item in subjects. If no item exists, _.get() will return undefined, which can be replaced with a default value. In this case, we don't want to use an empty string as a default value, since the order would change. Instead I'm checking if the value is a string, if it is I use lower case on it, if not I return it as is.
const arr = [{"id":"1","name":"peter","subject":[{"id":"1","name":"maths"},{"id":"2","name":"social"}]},{"id":"2","name":"david","subject":[{"id":"2","name":"physics"},{"id":"3","name":"science"}]},{"id":"3","name":"Justin","subject":[]}]
const result = _.orderBy(arr, o => {
const name = _.get(o, 'subject[0].name')
return _.isString(name) ? name.toLowerCase() : name
})
console.log(result)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.js"></script>
Use _.sortBy with a comparison/sorting function argument. Your function itself can look into the receiving arguments subject key (I think its the subject you want to compare?)
Since you have the question also tagged with ES6 here is an JS only solution via Array.sort:
let arr = [ { "id": "1", "name": "peter", "subject": [ { "id": "1", "name": "maths" }, { "id": "2", "name": "social" } ] }, { "id": "2", "name": "david", "subject": [ { "id": "2", "name": "physics" }, { "id": "3", "name": "science" } ] }, { "id": "3", "name": "Justin", "subject": [] }, ]
const result = arr.sort((a,b) =>
a.subject.length && b.subject.length
? a.subject[0].name.localeCompare(b.subject[0].name)
: a.subject.length ? -1 : 1)
console.log(result)

PowerShell- Merging JSON files

How to copy the objects of one array of a JSON file to an array of another JSON file using PowerShell? For Example I have one JSON file like:
"type": "Employee",
"Properties": [
{
"Name": "Raj",
"Id": "18111",
"email": "emp1#company.com",
"Position": "Manager",
"DateOfJoining": "16.10.14",
}
],
"Description": "Employee details"
and another JSON file as:
"type": "Employee",
"Properties": [
{
"Name": "Ram",
"Id": "44000",
"email": "emp2#company.com",
"Position": "Admin",
"DateOfJoining": "10.12.14",
},
{
"Name": "Paul",
"Id": "44002",
"email": "emp3#company.com",
"Position": "Programmer",
"DateOfJoining": "10.9.14",
},
],
"Description": "Employee details"
I want to copy the arrays from 1st JSON file to the 2nd JSON file.
You can try something like this:
$c1 = Convert-FromJson (gc file1.json -raw)
$c2 = Convert-FromJson (gc file2.json -raw)
$c3 = $c1.Properties + $c2.Properties
$c3 | ConvertTo-Json

How to Index & Search Nested Json in Solr 4.9.0

I want to index & search nested json in solr. Here is my json code
{
"id": "44444",
"headline": "testing US",
"generaltags": [
{
"type": "person",
"name": "Jayalalitha",
"relevance": "0.334",
"count": 1
},
{
"type": "person",
"name": "Kumar",
"relevance": "0.234",
"count": 1
}
],
"socialtags": {
"type": "SocialTag",
"name": "US",
"importance": 2
},
"topic": {
"type": "Topic",
"name": "US",
"score": "0.936"
}
}
When I try to Index, I'm getting the error "Error parsing JSON field value. Unexpected OBJECT_START"
When we tried to use Multivalued Field & index, we couldn't able to search using the multivalued field? Its returning "Undefined Field"
Also Please advice if I need to do any changes in schema.xml file?
You are nesting child documents within your document. You need to use the proper syntax for nested child documents in JSON:
[
{
"id": "1",
"title": "Solr adds block join support",
"content_type": "parentDocument",
"_childDocuments_": [
{
"id": "2",
"comments": "SolrCloud supports it too!"
}
]
},
{
"id": "3",
"title": "Lucene and Solr 4.5 is out",
"content_type": "parentDocument",
"_childDocuments_": [
{
"id": "4",
"comments": "Lots of new features"
}
]
}
]
Have a look at this article which describes JSON child documents and block joins.
Using the format mentioned by #qux you will face "Expected: OBJECT_START but got ARRAY_START at [16]",
"code": 400
as when JSON starting with [....] will parsed as a JSON array
{
"id": "44444",
"headline": "testing US",
"generaltags": [
{
"type": "person",
"name": "Jayalalitha",
"relevance": "0.334",
"count": 1
},
{
"type": "person",
"name": "Kumar",
"relevance": "0.234",
"count": 1
}
],
"socialtags": {
"type": "SocialTag",
"name": "US",
"importance": 2
},
"topic": {
"type": "Topic",
"name": "US",
"score": "0.936"
}
}
The above format is correct.
Regarding searching. Kindly use the index to search for the elements of the JSON array.
The workaround for this can be keeping the whole JSON object inside other JSON object and the indexing it
I was suggesting to keep the whole data inside another JSON object. You can try the following way
{
"data": [
{
"id": "44444",
"headline": "testing US",
"generaltags": [
{
"type": "person",
"name": "Jayalalitha",
"relevance": "0.334",
"count": 1
},
{
"type": "person",
"name": "Kumar",
"relevance": "0.234",
"count": 1
}
],
"socialtags": {
"type": "SocialTag",
"name": "US",
"importance": 2
},
"topic": {
"type": "Topic",
"name": "US",
"score": "0.936"
}
}
]
}
see the syntax in http://yonik.com/solr-nested-objects/
$ curl http://localhost:8983/solr/demo/update?commitWithin=3000 -d '
[
{id : book1, type_s:book, title_t : "The Way of Kings", author_s : "Brandon Sanderson",
cat_s:fantasy, pubyear_i:2010, publisher_s:Tor,
_childDocuments_ : [
{ id: book1_c1, type_s:review, review_dt:"2015-01-03T14:30:00Z",
stars_i:5, author_s:yonik,
comment_t:"A great start to what looks like an epic series!"
}
,
{ id: book1_c2, type_s:review, review_dt:"2014-03-15T12:00:00Z",
stars_i:3, author_s:dan,
comment_t:"This book was too long."
}
]
}
]'
supported from solr 5.3

ActiveRecord get array inside array with three tables

I'm trying to output a json string with the ActiveRecord system in the Codeigniter framework.
The right syntax for my json string need to be:
{
"data": [
[
{
"name": "xxxx",
"city": "xxx",
"address": "xxx",
"image": "xxx",
"marketId": "1",
"products": [
"Id": "36",
"productId": "36",
"price": "120",
"discounts": "1",
"title": "xxx",
"category": "2",
"weight": "12.5",
"code": "EA123",
"isUnitized": "0",
"description": "xxxx",
"changed": "2014-04-08 15:09:16",
"units": "xxx"
]
}
]
]
Pay attention to the "products" array.
But the string that i'm getting from the code is not right, here is the wrong string:
{
"data": [
[
{
"name": "xxx",
"city": "xxx",
"address": "xx x",
"image": "xxx",
"marketId": "1",
"Id": "36",
"productId": "36",
"price": "120",
"discounts": "1",
"title": "xxx",
"category": "2",
"weight": "12.5",
"code": "EA123",
"isUnitized": "0",
"description": "xxx",
"changed": "2014-04-08 15:09:16",
"units": "xxx"
}
]
]
You can see that the product array is't showing like an array but as a regular string inside the main array.
Here is the code that have I built:
$this->db->select('*');
$this->db->from('markets');
$this->db->where("markets.marketId", $marketId);
$this->db->join('linkedPrices', 'linkedPrices.marketId = markets.marketId');
$this->db->join('products', 'products.Id = linkedPrices.productId');
$this->db->order_by("linkedPrices.price", "DESC");
$output[] = $this->db->get()->result();
So you can see here the join between the table. The goal is to show the products tables as individual array inside the markets array as you can see at the top example of the json string.
No not this way you gonna have array of products foreach your dataset it can be done by looping over your results and fetch the relevant product data
$result=new stdClass();
$this->db->select('*');
$this->db->from('markets');
$this->db->where("markets.marketId", $marketId);
$this->db->join('linkedPrices', 'linkedPrices.marketId = markets.marketId');
$this->db->order_by("linkedPrices.price", "DESC");
$result = $this->db->get()->result();
foreach($result as $r){
$result->products=$this->db->select('*')
->from('products')
->where('id',$r->productId)
->get()
->result();
}
$output[]=json_encode($result);