I am trying to do a simple search, using NEST for customers given specific customer locations. The POCOS are:
class Customer
{
public int CustomerId { get; set; }
public string CustomerName { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Identifiers { get; set; }
public string isIndividual { get; set; }
public double Balance { get; set; }
public List<CustomerLocation> Locations { get; set; }
class CustomerLocation
{
public int CustomerLocationId { get; set; }
public string StreetLine1 { get; set; }
public string Streetline2 { get; set; }
public string City { get; set; }
}
Currently I am using this search routine - but it fails:
var searchResponse = _client.Search<Customer>(s => s
.Query(q => q
.HasChild<CustomerLocation >(hp => hp
.Query(qq => qq
.Match(m => m
.Field(f => f.City )
.Query(queryText)
)
)
)
)
.Size(500)
);
The error message provided is:
System.Exception HResult=0x80131500 Message=Invalid search. Error is: Invalid NEST response built from a unsuccessful (400) low level call on POST: /customers/_search?typed_keys=true
at System.Net.HttpWebRequest.GetResponse() at Elasticsearch.Net.HttpWebRequestConnection.Request[TResponse](RequestData requestData) in C:\Users\russc\source\elasticsearch-net\src\Elasticsearch.Net\Connection\HttpWebRequestConnection.cs:line 63
Any ideas - much appreciated.
The relationship between customers and locations is not a parent/child relationship in Elasticsearch terms, which is required in order to use the has_child
query.
Unless explicitly mapped, the Locations
property on Customer
will be an object
type mapping, which would allow you to do
var queryText = "Sydney";
var searchResponse = client.Search<Customer>(s => s
.Query(q => q
.Match(m => m
.Field(f => f.Locations.First().City)
.Query(queryText)
)
)
.Size(500)
);
Note: f => f.Locations.First().City
is simply an expression to build a path to the JSON field in a strongly typed fashion, by navigating the object graph. It does not mean "the first location's city", but evaluates to "any location's city".
This generates the following query
{
"query": {
"match": {
"locations.city": {
"query": "Sydney"
}
}
},
"size": 500
}
With the given POCO structure however, it's likely that you'll want to search across multiple location properties. In that case, Locations
should be explicitly mapped as a nested
data type.
When mapped as a nested data type, the query would be
var queryText = "Sydney";
var searchResponse = client.Search<Customer>(s => s
.Query(q => q
.Nested(n => n
.Path(p => p.Locations)
.Query(nq => nq
.Match(m => m
.Field(f => f.Locations.First().City)
.Query(queryText)
)
)
)
)
.Size(500)
);
User contributions licensed under CC BY-SA 3.0