How to upload/index a GeoJson file in Elasticsearch using NEST(C#) - c#

I have GeoJson File with me which i want to index on Elastic Search through NEST
But Due to lack of expertise I am having trouble in indexing the document
I have created a class which represent the Mapping on ElasticSearch:
public class GeoDocument
{
[Nest.Keyword(Name = "DocId")]
public string DocId { get; set; }
[Nest.GeoShape(Name = "GeoField")]
public object GeoField { get; set; }
}
But when i use this Mapping to index a Document
var polygon = "{\"type\":\"Polygon\",\"coordinates\":[[[5.856956,51.002753],[5.856928,51.002771],[5.856687,51.002853],[5.856956,51.002753]]]}";
var geoDocument = new GeoJson
{
DocId = "1",
GeoField = JsonConvert.DeserializeObject<object>(polygon)
};
var IndexResponse = client.IndexDocument(geoDocument);
I get a Result Something like This
"_source": {
"DocId": "1",
"GeoField": [
[
[]
],
[
[
[
[
[],
[]
],
[
[],
[]
],
[
[],
[]
],
[
[],
[]
]
]
]
]
]
}
}

In order to make that JObject saved correctly, you have to tell the ElasticClient to use NewtonSoft .Net serializer.
Install NEST.JsonNetSerializer package
Reference the JsonNetSerializer in your ConnectionSettings
If you get 400 after changing the settings, you might need to create a new Index.
Sample code
using Nest;
using Elasticsearch.Net;
using Nest.JsonNetSerializer;
SingleNodeConnectionPool node = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
ConnectionSettings settings = new ConnectionSettings(
node,
JsonNetSerializer.Default
);
settings.DefaultMappingFor<GeoDocument>(m => m.IndexName("project2"));
ElasticClient client = new ElasticClient(settings);
// This is Supposed to be GeoDocument as per your question.
GeoDocument geoDocument = new GeoDocument
{
DocId = "1",
GeoField = JObject.Parse(polygon)
// GeoField = JsonConvert.DeserializeObject<object>(polygon) // <-- Works too.
};
IndexResponse IndexResponse = client.IndexDocument(geoDocument);
Response
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 1.0,
"hits": [
{
"_index": "project2",
"_type": "_doc",
"_id": "COQRXW8BNG2RJmIOyoO0",
"_score": 1.0,
"_source": {
"DocId": "1",
"GeoField": {
"type": "Polygon",
"coordinates": [
[
[
5.856956,
51.002753
],
[
5.856928,
51.002771
],
[
5.856687,
51.002853
],
[
5.856956,
51.002753
]
]
]
}
}
}
]
}
}

Related

Transform nested JSON arrays into an array of JSON objects

I have the following set of variable JSON data where the first row is the list of element names and the other rows represent the list of element values:
[
[
"category",
"author",
"title",
"price"
],
[
"reference",
"Nigel Rees",
"Sayings of the Century",
"8.95"
],
[
"fiction",
"Evelyn Waugh",
"Sword of Honour",
"12.99"
],
[
"fiction",
"Herman Melville",
"Moby Dick",
"8.99"
],
[
"fiction",
"J. R. R. Tolkien",
"The Lord of the Rings",
"22.99"
]
]
I want to build the following type of JSON object from the data:
{
"book": [
{
"category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{
"category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{
"category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{
"category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
]
}
How can I build my JSON object which should be identical to the above. I don't see any direct support for doing this using JSON.NET APIs.
Any help is greatly appreciated.
This is just an idea to get you on the right track.
JObject obj = new JObject();
var child = new JArray();
var child2 = new JObject();
child2.Add("category", "references");
child.Add(child2);
obj.Add("book", child);
var result = obj.ToString();
I won't do the string parsing for you, i think you should be able to handle that.
The piece of code I've given produces the following JSON:
{
"book": [
{
"category": "references"
}
]
}
Hope this helps.
You can do this transformation using Json.Net's LINQ-to-JSON API:
JArray array = JArray.Parse(origJson);
string[] keys = array.First().Select(t => t.ToString()).ToArray();
JArray array2 =
new JArray(array.Skip(1).Select(a =>
new JObject(a.Select((t, i) =>
new JProperty(keys[i], t)
))
));
JObject obj = new JObject(new JProperty("book", array2));
string finalJson = obj.ToString();
Fiddle: https://dotnetfiddle.net/kMyHOe

Write to JArray in JObject

I have a JSON file.
{
"time": [
{
"id": "9999",
"name": "Foo",
"subitem": [
{
"name": "Bar",
"id": "99990",
"visible": true,
"subitem": [
{
"id": "999901",
"name": "Flex",
"visible": true
},
{
"name": "Bear",
"id": "999902",
"visible": true
},
{
"name": "James",
"id": "999903",
"visible": true
}
]
},
{
"name": "Smith",
"id": "999966",
"visible": true
},
{
"name": "John",
"id": "999933",
"visible": true
}
],
"visible": true
},
{
"name": "Doe",
"id": "1111",
"visible": true,
"subitem": [
{
"name": "Jack",
"id": "111111",
"visible": true
},
{
"name": "Wilson",
"id": "111188",
"visible": true
},
{
"name": "Andy",
"id": "111144",
"visible": true
},
{
"name": "Gibbs",
"id": "111155",
"visible": true
}
]
}
],
"name": "asdf",
"id": "13",
"visible": true
}
I also have a JObject and a method to get all the JSON data and store it in this object.
json1 = ti.GetTimeItems();
I have 2 methods in another class to write to the JSON file. Where datafolder is the path.
public void WriteToJson(JObject obj)
{
string fileName = dataFolder + "json1.json";
WriteToJson(fileName, obj);
}
private void WriteToJson(string fileName, JObject obj)
{
using (StreamWriter file = File.CreateText(fileName))
using (JsonTextWriter writer = new JsonTextWriter(file))
{
obj.WriteTo(writer);
}
}//end WriteToJson
Then i have a windows form where i want to take the text from 2 textboxes and add these to the JSON file.
Finally i have my click event
private void button1_Click_1(object sender, EventArgs e)
{
//string json = File.ReadAllText(url);
//JArray time = (JArray)json1.SelectToken("time");
json1.Add(new JObject(
new JProperty("name", textBoxName.Text),
new JProperty("id", textBoxId.Text),
new JProperty("visible", true)));
ti.WriteToJson(json1);
}
My problem is that i cannot seem to write to the array "time" in the JObject.
I managed to write to the file but in root instead of inside the array.
I have tried json1.SelectToken("time") and lots of different approaches, like this one http://stackoverflow.com/questions/15413825/how-do-you-add-a-jtoken-to-an-jobject#15782238 and also some approaches from the Newtonsoft documentation.
Any help is appriciated
Problem solved by ((JArray)json1.GetValue("time")). Selecting the array in the JObject json1 and adding to that instead of the root.
Hope this will help someone.
((JArray)json1.GetValue("time")).Add(
new JObject(
new JProperty("name", textBoxName.Text),
new JProperty("id", textBoxId.Text),
new JProperty("visible", true)));
ti.WriteToJson(json1);

c# can't build json hierarchy correctly using newtonsoft

I looked at this SO question but it doesn't address my needs: Build JSON Hierarchy from Structured Data
The problem: When trying to build the json, the nesting of children isn't done correctly. The children property should contain 1 or more name array items like this:
"children": [{
"name": "XXX - Level XXX",
...instead it is generated as:
"children": []
Here's a dotnet fiddle with more code details:
I'm trying to build the tree by using json.net .Last to grab the last child and then add a JObject to that child but that isn't working out too well for me.
The main data structure used to build the json :
Dictionary<int, Industry>();
The desired json structure should be:
{
"name": "XX Level XX",
"children": [{
"name": "XXX - Level XXX",
"children": [{
"name": "XXXX - Level XXXX",
"children": [{
"name": "XXXXX - Level XXXXX",
"children": [{
"name": "XXXXXX - Level XXXXXX"
}]
}]
}]
}]
}
The actual output is:
{
"name": "XX-Level XX",
"children": [{
"name": "XXX-Level XXX",
"children": []
}, {
"name": "XXXX-Level XXXX",
"children": []
}, {
"name": "XXXXX-Level XXXXX",
"children": []
}, {
"name": "XXXXXX-Level XXXXXX",
"children": []
}
]
}
Here's the code that builds the json:
dynamic relationship = new JObject();
relationship.name = relationships[0].Industries[1].Name;
relationship.children = new JArray();
var lftIndustries = relationships[0].Industries.Where(k => k.Key > 1);
foreach (var item in lftIndustries)
{
//not good enough, need to get deepest, empty "children" node
// and add "industry" to it
var node = ((JContainer)relationship).Last;
var childArray = (JArray)((JContainer) node).Last;
var industry = new JObject(new JProperty("name", item.Value.Name), new JProperty("children", new JArray()));
childArray.Add(industry);
}
json = relationship.ToString();
I thought that using json.net .Last and .Next would be the answer.
try this in your foreach loop and tell me if it is whats youre looking for:
JToken currentContainer = null;
foreach (var item in lftIndustries)
{
//not good enough, need to get deepest, empty "children" node
// and add "industry" to it
if (currentContainer != null)
{
var node = ((JContainer)currentContainer).Last;
var childArray = (JArray)((JContainer) node).Last;
var industry = new JObject(new JProperty("name", item.Value.Name), new JProperty("children", new JArray()));
childArray.Add(industry);
currentContainer = industry;
}
else
{
var node = ((JContainer)relationship).Last;
var childArray = (JArray)((JContainer) node).Last;
var industry = new JObject(new JProperty("name", item.Value.Name), new JProperty("children", new JArray()));
childArray.Add(industry);
currentContainer = industry;
}
}
The result is this:
{
"name": "XX-Level XX",
"children": [
{
"name": "XXX-Level XXX",
"children": [
{
"name": "XXXX-Level XXXX",
"children": [
{
"name": "XXXXX-Level XXXXX",
"children": [
{
"name": "XXXXXX-Level XXXXXX",
"children": []
}
]
}
]
}
]
}
]
}
Heres the fiddle: https://dotnetfiddle.net/1yzTGU

get Specific Id from json file

this is my json file
{
{
"#odata.context": "https://api.onedrive.com/v1.0/$metadata#drives('me')/items('root')/children/$entity",
"createdBy": {
"application": {
"displayName": "Nopbackup",
"id": "4c190e01"
},
"user": {
"displayName": "pallav jha",
"id": "611c19eb038d5aa1"
}
},
"createdDateTime": "2016-05-12T07:25:36.463Z",
"cTag": "adDo2MTFDMTlFQjAzOEQ1QUExITEyNC42MzU5ODYzODk5MTI3MDAwMDA",
"eTag": "aNjExQzE5RUIwMzhENUFBMSExMjQuMw",
"id": "611C19EB038D5AA1!124",
"lastModifiedBy": {
"application": {
"displayName": "Nopbackup",
"id": "4c190e01"
},
"user": {
"displayName": "pallav jha",
"id": "611c19eb038d5aa1"
}
},
"lastModifiedDateTime": "2016-05-12T08:36:31.27Z",
"name": "Nopbackup",
"parentReference": {
"driveId": "611c19eb038d5aa1",
"id": "611C19EB038D5AA1!105",
"path": "/drive/root:"
},
"size": 0,
"webUrl": "https://onedrive.live.com/redir?resid=611C19EB038D5AA1!124",
"fileSystemInfo": {
"createdDateTime": "2016-05-12T07:25:36.463Z",
"lastModifiedDateTime": "2016-05-12T08:36:31.27Z"
},
"folder": {
"childCount": 0
}
}
}
i want to get this "id": "4c190e01" from json
dynamic value = Newtonsoft.Json.JsonConvert.DeserializeObject(result);
string id = Convert.ToString(value.id[0]);
this is my code but i am not getting 4c190e01 id
rewrite your code as following...
dynamic valuePoco = Newtonsoft.Json.JsonConvert.DeserializeObject(result);
string id = Convert.ToString(valuePoco.createdBy.application.id);
You can use the path to the desired property. If you want to select the element with 4c190e01 as id, you can use
string id = value.createdBy.application.id;
or
string id = value.lastModifiedBy.application.id;
depending on your needs.
As it was pointed out, you'd need to fix your JSON first and remove the first { and the last }
First thing first, Your json is invalid.
You've to remove one { from top and } from the bottom and then use the following code:
dynamic jsonObj = JsonConvert.DeserializeObject(result);
string id = jsonObj.createdBy.application.id.ToString();

DeserializeObject with newtonsoft.json without using Class

I have this Joson
{
"Sucess": true,
"Msg": "OK",
"Ret": {
"First": 0,
"Next": true,
"Total": 60,
"Itens": [
{
"ID": 212121,
"Name": "uuuuuuuuuuuuuuuuuuuuuuuu",
"LcID": 9898,
"Oclao": false,
"Lal": {
"ID": 12202,
"Name": "pppppppppppppppppp",
"Pais": "Brasil",
"Dtc": 0.0
},
"Subtipo": {
"ID": 7458,
"Desc": "mnmnmnmnn"
},
"Tipo": {
"Sit": "cor1",
"Sitrm": 0,
"Name": "Shsdfow"
},
"Qtde": 0,
"Qntcoes": 0,
"Pubum": "adfsdfsdfs",
"Evias": {
"arq": {
"Mo": [
"site.com"
],
"Moir": [
"site.com"
]
}
}
},
{
"ID": 9797878,
"Name": "uuuuuuuuuuuuuuuuuuuuuuuu",
"LcID": 9898,
"Oclao": false,
"Lal": {
"ID": 12332,
"Name": "pppppppppppppppppp",
"Pais": "Brasil",
"Dtc": 0.0
},
"Subtipo": {
"ID": 7458,
"Desc": "mnmnmnmnn"
},
"Tipo": {
"Sit": "cor1",
"Sitrm": 0,
"Name": "Shsdfow"
},
"Qtde": 0,
"Qntcoes": 0,
"Pubum": "adfsdfsdfs",
"Evias": {
"arq": {
"Mo": [
"site.com"
],
"Moir": [
"site.com"
]
}
}
}
]
}
}
I would read the array "items" by the field names without using a class to Deserialize, what I did so far was:
JObject jRetorno = JObject.Parse(strJson);
IList<JToken> jItens = jRetorno["Itens"].Children().ToList();
The example http://www.newtonsoft.com/json/help/html/SerializingJSONFragments.htm that uses a class for this, as my json always changes, wanted something like:
strReturn = jItens[1]["ID"];
strReturn = jItens[1]["Name"];
strReturn = jItens[2]["ID"];
strReturn = jItens[2]["Name"];
strReturn = jItens[3]["ID"];
strReturn = jItens[3]["Name"];
Thanks!
You're not that far off. The data you want is one level further down, inside the Ret object. Try it like this:
JObject jRetorno = JObject.Parse(strJson);
IList<JToken> jItens = jRetorno["Ret"]["Itens"].Children().ToList();
foreach (JToken jt in jItens)
{
Console.WriteLine(jt["ID"]);
Console.WriteLine(jt["Name"]);
}
Fiddle: https://dotnetfiddle.net/TwtGyz

Categories

Resources