Elasticsearch throw Elasticsearch.Net.UnexpectedElasticsearchClientException - elasticsearch

I have a problem with Elasticsearch.Net.UnexpectedElasticsearchClientException:
I tried change nest edition(eg:5.xxx,2.xxx,6.xxx) and can not fixed this problem,I can't found 7.xxx in nuget,so what should I try again to fixed this?
Exception is:
Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Int64' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly.
To fix this error either change the JSON to a JSON primitive value (e.g. string, number, boolean, null) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.
Path 'hits.total.value', line 1, position 115.”
var settings = new ConnectionSettings(new Uri("http://localhost:9200")).DefaultIndex("my-application");
var client = new ElasticClient(settings);
IEnumerable<Person> persons = new List<Person>
{
new Person()
{
Id = "4",
Firstname = "aaa",//Boterhuis-040
Lastname = "Gusto-040",
Chains = new string[]{ "a","b","c" },
},
new Person()
{
Id = "5",
Firstname = "sales#historichousehotels.com",
Lastname = "t Boterhuis 1",
Chains = new string[]{ "a","b","c" },
},
new Person()
{
Id = "6",
Firstname = "Aberdeen #110",
Lastname = "sales#historichousehotels.com",
Chains = new string[]{ "a","b","c" },
},
new Person()
{
Id = "7",
Firstname = "Aberdeen #110",
Lastname = "t Boterhuis 2",
Chains = new string[]{ "a","b","c" },
},
new Person()
{
Id = "8",
Firstname = "Aberdeen #110",
Lastname = "t Boterhuis 2",
Chains = new string[]{ "a","b","c" },
},
};
client.IndexMany<Person>(persons, "test");
var rs = client.Search<Person>(s => s.Index("test"));
var response = rs.Documents;

Related

Elasticsearch - NEST - Upsert

I have the following two classes
Entry
public class Entry
{
public Guid Id { get; set; }
public IEnumerable<Data> Data { get; set; }
}
EntryData
public class EntryData
{
public string Type { get; set; }
public object Data { get; set; }
}
I have a bunch of different applications that produces messages to a queue that I then consume in a separate application to store that data in elasticsearch.
Im using a CorrelationId for all the messages and I want to use this ID as the ID in elasticsearch.
So given the following data:
var id = Guid.Parse("1befd5b62b944b4aa600c85632159e11");
var entries = new List<Entry>
{
new Entry
{
Id = id,
Data = new List<EntryData>
{
new EntryData
{
Data = DateTime.UtcNow,
Type = "APPLICATION1_Received"
},
new EntryData
{
Data = DateTime.UtcNow,
Type = "APPLICATION1_Validated"
},
new EntryData
{
Data = DateTime.UtcNow,
Type = "APPLICATION1_Published"
},
}
},
new Entry
{
Id = id,
Data = new List<EntryData>
{
new EntryData
{
Data = DateTime.UtcNow,
Type = "APPLICATION2_Received"
},
new EntryData
{
Data = DateTime.UtcNow,
Type = "APPLICATION2_Validated"
},
new EntryData
{
Data = DateTime.UtcNow,
Type = "APPLICATION2_Published"
},
}
},
new Entry
{
Id = id,
Data = new List<EntryData>
{
new EntryData
{
Data = DateTime.UtcNow,
Type = "APPLICATION3_Received"
},
new EntryData
{
Data = DateTime.UtcNow,
Type = "APPLICATION3_Validated"
},
new EntryData
{
Data = DateTime.UtcNow,
Type = "APPLICATION3_Published"
},
}
},
};
I want this to be saved as one entry in elasticsearch where ID == 1befd5b6-2b94-4b4a-a600-c85632159e11 and a data array that contains 9 elements.
Im struggling a bit with getting this to work, when trying the following:
var result = await _elasticClient.BulkAsync(x => x.Index("journal").UpdateMany(entries, (descriptor, entry) => {
descriptor.Doc(entry);
return descriptor.Upsert(entry);
}), cancellationToken);
But this is just overwriting whatever already exists in the data array and the count is 3 instead of 9 (only the Application3 entries are saved).
So, is it possible to do what I want to do? I never worked with elasticsearch before so it feels like maybe Im missing something simple here... :)
Managed to solve it like this:
var result = await _elasticClient.BulkAsync(x => x.Index("journal").UpdateMany(entries, (descriptor, entry) => {
var script = new InlineScript("ctx._source.data.addAll(params.data)")
{
Params = new Dictionary<string, object> {{"data", entry.Data}}
};
descriptor.Script(b => script);
return descriptor.Upsert(entry);
}), cancellationToken);

C# Linq how to use group by to get the desired output

I have the following classes
public class Product
{
public string PNo {get;set;}
public String GCode {get;set;}
public IList<Detail> Details {get;set;}
}
public class Detail{
public string Color {get;set;}
public string Size {get;set;}
}
And i have the data in an array as below
PNO GCode Color Size Amount
12345 GCC A L 1
12345 GCC V M 2
12345 GCC C S 3
12345 GCC D XL 4
12345 GCC E XS 5
How do i get the following output using groupby so that my output could like shown below
Expected output:
{
PNO: 12345,
GCode: GCC,
options:[
{Color:A, Size:L, Amount: 1},
{Color:V, Size:M, Amount: 2},
{Color:C, Size:S, Amount: 3},
{Color:D, Size:XL, Amount: 4},
{Color:E, Size:XS, Amount: 5}
]
}
Thanks
Given the contract you defined. I think below code snippet is OK to generate the JSON you want, I use anonymous object a lot, you can replace with you entity class.
products.GroupBy(product => new
{
product.PNo,
product.GCode
})
.Select(productGroup => new
{
productGroup.Key.PNo,
productGroup.Key.GCode,
options = productGroup.SelectMany(product => product.Details.Select(detail => new
{
detail.Color,
detail.Size,
detail.Amount
}))
});
Hope it helps.
This will get you that expected output:
Query Syntax:
var result = (from item in collection
group item by new { item.PNO, item.GCode } into grouping
select new Product
{
PNo = grouping.Key.PNO,
GCode = grouping.Key.GCode,
Details = grouping.Select(item => new Detail { Color = item.Color, Size = item.Size, Amount = item.Amount }).ToList()
}).ToList();
Method Syntax:
var result = collection.GroupBy(item => new { item.PNO, item.GCode })
.Select(grouping => new Product
{
PNo = grouping.Key.PNO,
GCode = grouping.Key.GCode,
Details = grouping.Select(item => new Detail { Color = item.Color, Size = item.Size, Amount = item.Amount }).ToList()
}).ToList();
Test Data:
List<dynamic> collection = new List<dynamic>()
{
new { PNO = "12345", GCode = "GCC", Color = "A", Size="L", Amount=1 },
new { PNO = "12345", GCode = "GCC", Color = "V", Size="M", Amount=2 },
new { PNO = "12345", GCode = "GCC", Color = "C", Size="S", Amount=3 },
new { PNO = "12345", GCode = "GCC", Color = "D", Size="XL", Amount=4 },
new { PNO = "12345", GCode = "GCC", Color = "E", Size="XS", Amount=5 },
};

Creating a JSON String from a Swift object in Xcode 7+

I have the following class that I need to convert into a JSON String using Xcode 7 and above. In the previous version of Xcode there was a JSONSerelization.toJson(AnyObject) function available, however does not appear in Xcode7 .
I need to convert the following class :
struct ContactInfo
{
var contactDeviceType: String
var contactNumber: String
}
class Tradesmen
{
var type:String = ""
var name: String = ""
var companyName: String = ""
var contacts: [ContactInfo] = []
init(type:String, name:String, companyName:String, contacts [ContactInfo])
{
self.type = type
self.name = name
self.companyName = companyName
self.contacts = contacts
}
I Have set up my test data as follows
contactType =
[
ContactInfo(contactDeviceType: "Home", contactNumber: "(604) 555-1111"),
ContactInfo(contactDeviceType: "Cell", contactNumber: "(604) 555-2222"),
ContactInfo(contactDeviceType: "Work", contactNumber: "(604) 555-3333")
]
var tradesmen = Tradesmen(type: "Plumber", name: "Jim Jones", companyName: "Jim Jones Plumbing", contacts: contactType)
Any help or direction would be appreciated.
I do not think that there is any direct way, even in previous Xcode. You will need to write your own implementation. Something like below:
protocol JSONRepresenatble {
static func jsonArray(array : [Self]) -> String
var jsonRepresentation : String {get}
}
extension JSONRepresenatble {
static func jsonArray(array : [Self]) -> String {
return "[" + array.map {$0.jsonRepresentation}.joinWithSeparator(",") + "]"
}
}
And then implement JSONRepresentable in your modals like below:
struct ContactInfo: JSONRepresenatble {
var contactDeviceType: String
var contactNumber: String
var jsonRepresentation: String {
return "{\"contactDeviceType\": \"\(contactDeviceType)\", \"contactNumber\": \"\(contactNumber)\"}"
}
}
struct Tradesmen: JSONRepresenatble {
var type:String = ""
var name: String = ""
var companyName: String = ""
var contacts: [ContactInfo] = []
var jsonRepresentation: String {
return "{\"type\": \"\(type)\", \"name\": \"\(name)\", \"companyName\": \"\(companyName)\", \"contacts\": \(ContactInfo.jsonArray(contacts))}"
}
init(type:String, name:String, companyName:String, contacts: [ContactInfo]) {
self.type = type
self.name = name
self.companyName = companyName
self.contacts = contacts
}
}

Use a Linq statement to perform outer join

Starting with the collection below, what Linq statement do I need to return a results set that satisfies the test?
private List<dynamic> _results;
[SetUp]
public void SetUp()
{
_results = new List<dynamic>
{
new {Id = 1, Names = new[] {"n1"}, Tags = new[] {"abc", "def"}},
new {Id = 2, Names = new[] {"n2", "n3"}, Tags = new[] {"ghi"}},
new {Id = 3, Names = new[] {"n1", "n3"}, Tags = new[] {"def", "xyz"}},
new {Id = 4, Names = new[] {"n4"}, Tags = new string[] {}}
};
}
private ILookup<string, string> GetOuterJoinedCollection(IEnumerable<dynamic> results)
{
// ???
}
[Test]
public void Test()
{
ILookup<string, string> list = GetOuterJoinedCollection(_results);
Assert.That(list.Count, Is.EqualTo(4));
Assert.That(list["n1"], Is.EquivalentTo(new [] { "abc", "def", "def", "xyz" }));
Assert.That(list["n2"], Is.EquivalentTo(new [] { "ghi" }));
Assert.That(list["n3"], Is.EquivalentTo(new [] { "ghi", "def", "xyz" }));
Assert.That(list["n4"], Is.EquivalentTo(new string[] { }));
}
Note: this is a follow up from a previous question: Convert Lambda into Linq Statement with nested for loop

Sort a list of Person objects using Linq

I need a query on sorting list of objects based on the category of property of the objects. I need the groups to be in an order other than the usual alphabetical order which I have seen in many other samples. I am using an example I took from elsewhere. How can I generate a list of Person objects based on HomeProvince but in terms of this ordering:
Ontario, Quebec, Alberta, Manitoba, British Columbia. The ordering within each group does not matter.
Person[] people = new Person[]
{
new Person() { FirstName = "Tony", LastName = "Montana", Age = 39, HomeProvince = "Ontario" },
new Person() { FirstName = "Bill", LastName = "Smith", Age = 23, HomeProvince = "Ontario" },
new Person() { FirstName = "Jane", LastName = "Doe", Age = 23, HomeProvince = "Alberta" },
new Person() { FirstName = "John", LastName = "Doe", Age = 23, HomeProvince = "Alberta" },
new Person() { FirstName = "Alex", LastName = "DeLarge", Age = 19, HomeProvince = "British Columbia" },
new Person() { FirstName = "Travis", LastName = "Bickle", Age = 42, HomeProvince = "Quebec" },
new Person() { FirstName = "Ferris", LastName = "Beuller", Age = 17, HomeProvince = "Manitoba" },
new Person() { FirstName = "Maggie", LastName = "May", Age = 23, HomeProvince = "Ontario" },
new Person() { FirstName = "Mickey", LastName = "Mouse", Age = 93, HomeProvince = "Alberta" },
new Person() { FirstName = "Frank", LastName = "Darabont", Age = 49, HomeProvince = "Ontario" }
};
You could do this:
// Provinces in the desired order
string[] provinces = { "Ontario", "Quebec", "Alberta", "Manitoba",
"British Columbia" };
var query = from province in provinces
join person in people on province equals person.HomeProvince
select person;
That will basically:
Ignore anyone not in the specified provinces
Return a sequence of people in the province order specified
If you need the people grouped by province, that's easy too:
var query = from province in provinces
join person in people on province equals person.HomeProvince
into grouped
select new { Province = province, People = grouped.ToList() };
Another option would be to create a mapping from province to "priority" and simply order by that. It really depends on exactly what you need as output.
I'm not sure if this is the best way but I would probably just get every person with Ontario as HomeProvince and add them to the array. Then repeat for Quebec and so on... I don't know any other way because what you need is "random".
I say array because that's what you used in your code sample. Obviously it doesn't matter what kind of container you use as long as you don't order them as you put them in or after they are in.

Resources