Reputation: 713
the documentation seems to indicate i can return a subset of fields instead of the entire document. here's my code:
var result = client.Search<MyObject>(s => s
.Fields(f => f.Title)
.Query(q => q
.QueryString(qs => qs
.OnField("title")
.Query("the"))));
i'm searching on the word 'the' on the 'title' field and wanting to just return 'title'. my result.Documents object contains 10 objects that are each null.
i do see the values i want but it's deep in the search response: result.Hits[0].Fields.FieldValues[0]...
is there a better way to get at the list of 'title' fields returned?
my mapping for the data (truncated) is this ...
{
"myidex": {
"mappings": {
"myobject": {
"properties": {
"title": {
"type": "string"
},
"artists": {
"properties": {
"id": {
"type": "string",
"index": "not_analyzed",
"analyzer": "fullTerm"
},
"name": {
"type": "string",
"index": "not_analyzed",
"analyzer": "fullTerm"
}
}
}
}
}
}
}
}
and my class objects are like this:
[Table("MyTable")]
[Serializable]
[ElasticType(Name="myobject")]
public class MyObject
{
[ElasticProperty]
public string Title { get; set; }
[JsonIgnore]
public string Artistslist { get; set; }
[ElasticProperty(Analyzer = "caseInsensitive")]
public List<Person> Artists { get; set; }
}
[Serializable]
public class Person
{
[ElasticProperty(Analyzer = "fullTerm", Index = FieldIndexOption.not_analyzed)]
public string Name { get; set; }
[ElasticProperty(Analyzer = "fullTerm", Index = FieldIndexOption.not_analyzed)]
public string Id { get; set; }
}
Artistslist comes from my data source (sql) then i parse it out into a new List object before indexing the data.
Upvotes: 3
Views: 6417
Reputation: 111
I found the solution in Nest's Github repo. They have created an issue about this problem. You should use FielddataFields instead of Fields.
https://github.com/elastic/elasticsearch-net/issues/1551
var result = client.Search<MyObject>(s => s
.FielddataFields(f => f.Title)
.Query(q => q
.QueryString(qs => qs
.OnField("title")
.Query("the"))));
and in response you see FieldSelections. You get the fields that you wanted.
Upvotes: 3
Reputation: 22555
I think this deeply nested value is do to a change in Elasticsearch 1.0 and how partial fields are now returned as arrays (See 1.0 Breaking Changes - Return Values for details.). This is addressed in the NEST 1.0 Breaking Changes documentation; in the Fields() vs SourceIncludes() section. It shows an example of using a FieldValue
helper method to gain access to these values. Based on that, try the following:
For all items:
foreach (var hit in result.Hits)
{
var title = hit.Fields.FieldValue<MyObject, string>(f => f.Title);
}
For a specific item:
var title = result.Hits.ElementAt(0)
.Fields.FieldValue<MyObject, string>(f => f.Title);
I know it is still a bit verbose but it should work for you and will handle the new array return formatting of Elasticsearch 1.0.
Upvotes: 4