Load Json Data using Pig - hadoop

I am trying to extract data from below mention json format by pig using jsonLoader():
{"Partition":"10","Key":"618897","Properties2":[{"K":"A","T":"String","V":"M "}, {"K":"B","T":"String","V":"N"}, {"K":"D","T":"String","V":"O"}]}
{"Partition":"11","Key":"618900","Properties2":[{"K":"A","T":"String","V":"W”"},{"K":"B","T":"String","V":"X"}, {"K":"C","T":"String","V":"Y"},{"K":"D","T":"String","V":"Z"}]}
Right now I am able to extract data from “partition” ,“key” and “V” for every array objects with the following code:
A= LOAD '/home/hduser/abc.jon' Using JsonLoader('Partition:chararray,Key:chararray,Properties2:{(K:chararray,T:chararray,V:chararray)},Timestamp:chararray');
B= foreach A generate $0,$1,BagToString(Properties2.V,'\t') as vl:chararray;
store B into './Result/outPut2';
From above code I am getting "Properties2" array value on the sequence basis not column basis, it is creating problem whenever sequence changed or new object comes in existence.
Please help me to extract data on the basis of column( K values.)
My Output
Expected Output
Thanks In Advance

You have two options here
1.Use elephant-bird which will give you a map of key and value.
A = LOAD '/apps/pig/json_sample' USING com.twitter.elephantbird.pig.load.JsonLoader('-nestedLoad') as (json:map[]);
B = FOREACH A GENERATE json#'Partition',json#'Key',json#'Properties2';
dump B;
will give you an output of :
(10,618897,{([T#String,K#A,V#M ]),([T#String,K#B,V#N]),([T#String,K#D,V#O])})
(11,618900,{([T#String,K#A,V#W”]),([T#String,K#B,V#X]),([T#String,K#C,V#Y]),([T#String,K#D,V#Z])})
Or you have to write a custom loader which has to do this
a).It should know what is the correct order of values that will be coming
for the key K
b).Go through each of these values and see if the json is missing any of this key and return an empty/null char for that location.
Am posting the getNext() method of the CustomJsonLoader which will do the same:
#Override
public Tuple getNext() throws IOException {
// TODO Auto-generated method stub
try {
boolean notDone = in.nextKeyValue();
if (!notDone) {
return null;
}
Text value = (Text) in.getCurrentValue();
List<String> valueList = new ArrayList<String>();
if (value != null) {
String jsonString = value.toString();
System.out.println(jsonString);
JSONParser parser = new JSONParser();
JSONObject obj = null;
try {
obj = (JSONObject) parser.parse(jsonString);
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("obj is "+obj);
if (obj != null) {
String partition = (String) obj.get("Partition");
String key = (String) obj.get("Key");
valueList.add(partition);
valueList.add(key);
JSONArray innArr = (JSONArray) obj.get("Properties2");
char[] innKeys = new char[] { 'A', 'B', 'C', 'D' };
Map<String,String> keyMap = new HashMap<String,String>();
for (Object innObj : innArr) {
JSONObject jsonObj = (JSONObject) innObj;
keyMap.put(jsonObj.get("K")+"",jsonObj.get("V")+"");
}
for (int i = 0; i < innKeys.length; i++) {
char ch = innKeys[i];
if (keyMap.containsKey(ch+"")) {
valueList.add(keyMap.get(ch+""));
}else{
valueList.add("");
}
}
Tuple t = tupleFactory.newTuple(valueList);
return t;
}
}
return null;
} catch (InterruptedException e) {
}
}
and register it and run :
REGISTER udf/CustomJsonLoader.jar
A = LOAD '/apps/pig/json_sample' USING CustomJsonLoader();
DUMP A;
(10,618897,M,N,,O)
(11,618900,W,X,Y,Z)
Hope this helps!

Related

LINQ/MVC webservice return json file or an empty array

i don't know really how to formulate this but what i want is to achieve is the following, read a JSON file from a storage (direct url) but if that JSON file does not exist it should return an empty array.
this is what i got so far (and works)
public object GetFromFile(int Code)
{
string uriPath = "http://mystorage.com/folder/" + Code + ".json";
var allText = (new WebClient()).DownloadString(uriPath);
object jsonObject = JsonConvert.DeserializeObject(allText);
return jsonObject;
}
it returns to me the requested list of codes as a array, now if the code does not exists on the storage, possible, then the webservice should just return and empty array []
desired result:
from file (works):
[{001},{002},{003}]
if file does not exist
[]
//The call to WebClient.DownloadString(string) will throw an exception if the
//uri does not exist, in your case, the json file does not exist
var allText = null;
object jsonObject = null;
try
{
allText = (new WebClient()).DownloadString(uriPath);
jsonObject = JsonConvert.DeserializeObject(allText);
}
catch(WebException ex)
{
jsonObject = new object[0];
}
It seems that you expect that the JSON-file contains a sequence of similar items, from the look of it a sequence of integer numbers.
If you already know that the JSON-file contains this type of objects, it is better to use the overload of DeserializeObject<int>.
IEnumerable<int> ReadNumbersFromWebClient(int Code)
{
string uriPath = "http://mystorage.com/folder/" + Code + ".json";
var downloadedText = DownloadText(uriPath);
return JsonConvert.DeserializeObject<int[]>(allText);
}
string DownloadText(string uriPath)
{
using (var webClient = new WebClient())
{
return webClient.DownloadString(uriPath);
}
}
You said that you wanted to return an empty sequence if the "file does not exist". I assume that you meant: "if the web client says there is no string to download"
I looked at WebClient.DownloadString, and I couldn't find what happens if you use an uriPath that does not exist. Do you get empty string, or an exception?
ICollection<int> ReadNumbersFromWebClient(int Code)
{
// in case of exception: return empty string
try
{
string uriPath = "http://mystorage.com/folder/" + Code + ".json";
var downloadedText = DownloadText(uriPath);
return JsonConvert.DeserializeObject<int[]>(allText);
}
catch (Exception exc) // or use specific exception
{
return new int[];
}
}
It would be neater if you let DownloadText catch the expression. In case of exception return empty string. Experiment what happens if you try to Deserialize an empty string. It will probably be an empty int[]

How to get a CNContact phone number(s) as string in Xamarin.ios?

I am attempting to retrieve the names and phone number(s) of all contacts and show them into tableview in Xamarin.iOS. I have made it this far:
var response = new List<ContactVm>();
try
{
//We can specify the properties that we need to fetch from contacts
var keysToFetch = new[] {
CNContactKey.PhoneNumbers, CNContactKey.GivenName, CNContactKey.FamilyName, CNContactKey.EmailAddresses
};
//Get the collections of containers
var containerId = new CNContactStore().DefaultContainerIdentifier;
//Fetch the contacts from containers
using (var predicate = CNContact.GetPredicateForContactsInContainer(containerId))
{
CNContact[] contactList;
using (var store = new CNContactStore())
{
contactList = store.GetUnifiedContacts(predicate, keysToFetch, out
var error);
}
//Assign the contact details to our view model objects
response.AddRange(from item in contactList
where item?.EmailAddresses != null
select new ContactVm
{
PhoneNumbers =item.PhoneNumbers,
GivenName = item.GivenName,
FamilyName = item.FamilyName,
EmailId = item.EmailAddresses.Select(m => m.Value.ToString()).ToList()
});
}
BeginInvokeOnMainThread(() =>
{
tblContact.Source = new CustomContactViewController(response);
tblContact.ReloadData();
});
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
and this is my update cell method
internal void updateCell(ContactVm contact)
{
try
{
lblName.Text = contact.GivenName;
lblContact.Text = ((CNPhoneNumber)contact.PhoneNumbers[0]).StringValue;
//var no = ((CNPhoneNumber)contact.PhoneNumbers[0]).StringValue;
//NSString a = new NSString("");
// var MobNumVar = ((CNPhoneNumber)contact.PhoneNumbers[0]).ValueForKey(new NSString("digits")).ToString();
var c = (contact.PhoneNumbers[0] as CNPhoneNumber).StringValue;
}
catch(Exception ex)
{
throw ex;
}
}
I would like to know how to retrieve JUST the phone number(s) as a string value(s) i.e. "XXXXXXXXXX". Basically, how to call for the digit(s) value.
this line of code
lblContact.Text = ((CNPhoneNumber)contact.PhoneNumbers[0]).StringValue;
throw a run time exception as specified cast is not valid
Yes, exception is correct. First of all, you don't need any casts at all, contact.PhoneNumbers[0] will return you CNLabeledValue, so you just need to write it in next way
lblContact.Text = contact.PhoneNumbers[0].GetLabeledValue(CNLabelKey.Home).StringValue
//or
lblContact.Text = contact.PhoneNumbers[0].GetLabeledValue(CNLabelPhoneNumberKey.Mobile).StringValue
or you may try, but not sure if it works
contact.PhoneNumbers[0].Value.StringValue
I got solution. Here is my code if any one required.
CNLabeledValue<CNPhoneNumber> numbers =
(Contacts.CNLabeledValue<Contacts.CNPhoneNumber>)contact.PhoneNumbers[0];
CNPhoneNumber number = numbers.Value;
string str = number.StringValue;
lblContact.Text = str;

C# Sort array of Objects by object type (Icomparable?)

I want to sort anarray by the object type. So all songs are together, all book are together, and all movies are together.
I am reading a file and determine what each object should be. then creating the object and adding it to the array.
EDIT: Here is the actual code.
static Media[] ReadData()
{
List<Media> things = new List<Media>();
try
{
String filePath = "resources/Data.txt";
string Line;
int counter = 0; // used to check if you have reached the max
number of allowed objects (100)
using (StreamReader File = new System.IO.StreamReader(filePath))
{
while ((Line = File.ReadLine()) != null)
{
This is where each object is created. The file
search for a key word in the beginning of the line, then
creates the corresponding object. It will split the
information on the first line of the object and will
read each line until a "-" character is found and
pass each line into the summary. The summary is then
decrypted and the created object is passed into an
array List. Finally if the array list reaches 100, it
will print "You have reach max number of objects" and
stop reading the file.
if (Line.StartsWith("BOOK"))
{
String[] tempArray = Line.Split('|');
//foreach (string x in tempArray){Console.WriteLine(x);} //This is used
for testing
Book tempBook = new Book(tempArray[1],
int.Parse(tempArray[2]), tempArray[3]);
while ((Line = File.ReadLine()) != null)
{
if (Line.StartsWith("-")){break;}
tempBook.Summary = tempBook.Summary + Line;
}
tempBook.Summary = tempBook.Decrypt();
things.Add(tempBook);
counter++;
}
else if (Line.StartsWith("SONG"))
{
String[] tempArray = Line.Split('|');
//foreach (string x in tempArray)
{Console.WriteLine(x);} //This is used for testing
Song tempSong = new Song(tempArray[1],
int.Parse(tempArray[2]), tempArray[3], tempArray[4]);
things.Add(tempSong);
counter++;
}
else if (Line.StartsWith("MOVIE"))
{
String[] tempArray = Line.Split('|');
//foreach (string x in tempArray)
{Console.WriteLine(x);} //This is used for testing
Movie tempMovie = new Movie(tempArray[1],
int.Parse(tempArray[2]), tempArray[3]);
while ((Line = File.ReadLine()) != null)
{
if (Line.StartsWith("-")) { break; }
tempMovie.Summary = tempMovie.Summary + Line;
}
tempMovie.Summary = tempMovie.Decrypt();
things.Add(tempMovie);
counter++;
}
if (counter == 100)
{
Console.WriteLine("You have reached the maximum number of media
objects.");
break;
}
}
File.Close();
}
}
return things.ToArray(); // Convert array list to an Array and return the
array.
}
In the main code, I have this:
Media[] mediaObjects = new Media[100];
Media[] temp = ReadData();
int input; // holds the input from a user to determin which action to take
for (int i = 0; i<temp.Length;i++){ mediaObjects[i] = temp[i]; }
I want the array of mediaObjects to be sorted by the what type of objects.
I have also used Icomparable to do an arrayList.sort() but still no luck.
public int CompareTo(object obj)
{
if (obj == null)
{
return 1;
}
Song temp = obj as Song;
if (temp != null)
{
//Type is a string
return this.Type.CompareTo(temp.Type);
}
else
{
return 1;
}
}
So I see you have BOOK, SONG and MOVIE types.
This is a classic case of implementing the IComparable interface - although you are correct with the interface name to implement, you are not using this correctly.
Create a base class by the name MediaObject - this will be the main one for your other types of objects you create.
Add the correct properties you need. In this case, the media type is the one in need.
Let this class implement IComparable to help you with the comparison.
override the CompareTo() method in the PROPER way
public class MediaObject : IComparable
{
private string mediaType;
public string MediaType
{
get {return mediaType;}
set {mediaType=value;}
}
public MediaObject(string mType)
{
MediaType = mType;
}
int IComparable.CompareTo(object obj)
{
MediaObject mo = (MediaObject)obj;
return String.Compare(this.MediaType,mo.MediaType); //implement a case insensitive comparison if needed (for your research)
}
}
You can now compare the MediaObject objects In your main method directly.
Thank for the advice. I ended up just reformating how I was creating the list while reading it. I made multiple lists for each object then just happened each one on to the master list so It showed up sorted. I wish I figured that out before I made this long post.
As far as I could find, you can't sort by the type of object in a generic array. If anyone has a better solution feel free to post it.

loopj JsonObject with inside JsonArray JsonObjects

I have a Webservice which give me back this:
{"result":[{"Id":"20","temperatura":"34","humedad":"29","Insertado":"2016-07-01 12:19:42"},{"Id":"21","temperatura":"34","humedad":"29","Insertado":"2016-07-01 12:34:42"},{"Id":"22","temperatura":"35","humedad":"28","Insertado":"2016-07-01 12:49:43"},{"Id":"23","temperatura":"35","humedad":"19","Insertado":"2016-07-01 13:29:06"},{"Id":"24","temperatura":"31","humedad":"18","Insertado":"2016-07-01 13:44:07"},{"Id":"25","temperatura":"33","humedad":"16","Insertado":"2016-07-01 13:59:10"}]}
This is an Object, which has and Array, and the array has many objects.
Here is my code. I am using loopj library-
private void CaptarParametros(String idObjeto) {
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
params.put(UtilitiesGlobal.SENSOR_ID, idObjeto);
RequestHandle post = client.post(this, SENSORS_URL, params, new JsonHttpResponseHandler() {
#Override
public void onStart() {
// called before request is started
}
#TargetApi(Build.VERSION_CODES.KITKAT)
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
// called when response HTTP status is "200 OK"
JSONObject jsonobject = null;
JSONObject dht11JSONbject = null;
JSONArray dht11JSONarray = null;
try {
jsonobject = new JSONObject(String.valueOf(response));
dht11JSONbject = jsonobject.getJSONObject("result");
dht11JSONarray = new JSONArray(dht11JSONbject);
JSONArray dht11 = dht11JSONarray.getJSONArray(0);
for (int i = 0; i < dht11JSONarray.length(); i++) {
JSONObject item = dht11.getJSONObject(i);
String temperatura = item.getString("temperatura");
String humedad = item.getString("temperatura");
//Log.i(UtilitiesGlobal.TAG, "onSuccess: loopj " + usuarioiJSONbject);
Log.i(UtilitiesGlobal.TAG, "onSuccess: loopj " + temperatura + humedad);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
But I get error like this:
org.json.JSONException: Value [{"Id":"19","temperatura":"35","humedad":"16","Insertado":"2016-07-01 12:19:24"}] at result of type org.json.JSONArray cannot be converted to JSONObject
I would appreciate any help.- I need to extract "temperature" and humedad" in separate arrays since later I have to use it in MPAndroidChat to make tow linechart, one chart for one set of parameters and another one for other parameters.
Solution is here:
try {
jsonobject = new JSONObject(String.valueOf(response));
//dht11JSONbject = jsonobject.getJSONObject("result");
List<String> allNames = new ArrayList<String>();
JSONArray cast = jsonobject.getJSONArray("result");
for (int i=0; i<cast.length(); i++) {
JSONObject parametrosdht11 = cast.getJSONObject(i);
String temperatura = parametrosdht11.getString("temperatura");
String humedad = parametrosdht11.getString("humedad");
allNames.add(temperatura);
allNames.add(humedad);
//Log.i(UtilitiesGlobal.TAG, "onSuccess: loopj " + usuarioiJSONbject);
Log.i(UtilitiesGlobal.TAG, "onSuccess: loopj " +"temperatura: "+ temperatura +" humedad: " +humedad);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
We have a String with many sub_objects, then we have to put them into an array or List.
Take the solution from:
how to parse JSONArray in android

Inserting values into database using JSP

<%
if (MultipartFormDataRequest.isMultipartFormData(request))
{
// Uses MultipartFormDataRequest to parse the HTTP request.
MultipartFormDataRequest mrequest = new MultipartFormDataRequest(request);
String todo = null;
if (mrequest != null) todo = mrequest.getParameter("todo");
if ( (todo != null) && (todo.equalsIgnoreCase("upload")) )
{
Hashtable files = mrequest.getFiles();
if ( (files != null) && (!files.isEmpty()) )
{
UploadFile file = (UploadFile) files.get("uploadfile");
if (file != null)
out.println("");
//out.println(report1);
String sever = mrequest.getParameter("sever");
String ease = mrequest.getParameter("ease");
String logo = "C:/uploads/"+file.getFileName(); // Uses the bean now to store specified by jsp:setProperty at the top.
String dana = mrequest.getParameter("danalysis");
String loc = mrequest.getParameter("loc");
String state = mrequest.getParameter("state");
String Sr = mrequest.getParameter("Sr");
String Doc_ID = mrequest.getParameter("doc");
String impact = mrequest.getParameter("impact");
String desc = mrequest.getParameter("desc");
String ref = mrequest.getParameter("ref");
String recom = mrequest.getParameter("recom");
try
{
String connectionURL = "jdbc:mysql://localhost:3306/mssg";
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection con=DriverManager.getConnection(connectionURL, "root","");
out.println("OK!\n");
PreparedStatement ps1=con.prepareStatement("insert into report values(?,?,?,?,?,?,?,?,?,?,?,?)");
ps1.setString(1,Doc_ID);
ps1.setString(2,Sr);
ps1.setString(3,sever);
ps1.setString(4,ease);
ps1.setString(5,state);
ps1.setString(6,loc);
ps1.setString(7,desc);
ps1.setString(8,impact);
ps1.setString(9,dana);
ps1.setString(10,logo);
ps1.setString(11,recom);
ps1.setString(12,ref);
int count=ps1.executeUpdate();
if(count > 0)
{
out.println("successfully inserted");
//response.sendRedirect("/index.jsp");
}
else
{
out.println("error occured");
}
}
catch (Exception e)
{
System.out.println("error in program:-"+e);
}
upBean.store(mrequest, "uploadfile");
}
else
{
out.println("<li>No uploaded files");
}
}
}
%>
In the above code I get all the values also file is uploading but not able to insert these values into database. I think I made a very small mistake, please tell me what is the problem in the above code. This code is working until connection but after prepare statement it's not working.
This is beacuse you have used try and catch block.
In the jsp page life cycle, the jsp page is translated in the servlets. so the code for the database connectivity will be automatically placed in the try catch block.
Just remove the try catch block.

Resources