3

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.

3
  • What version of NEST are you using? Commented May 16, 2014 at 1:55
  • pre-release version of nest and elasticsearch.net (via nuget). i believe it's 1.0.0 beta1 Commented May 16, 2014 at 12:53
  • If your result.Documents objects are null, it may be a mapping issue. Can you add your MyObject class definition to the question. Commented May 16, 2014 at 13:44

2 Answers 2

4

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.

Sign up to request clarification or add additional context in comments.

5 Comments

is right on the money here. The syntax for FieldValue will be updated in the next beta release to be way less verbose: github.com/elasticsearch/elasticsearch-net/pull/619
seemed like it would work, but that code won't compile... result.Hits[0].Fields.FieldValue<MyObject, string>(f => f.Title)... Cannot apply indexing with [] to an expression of type 'System.Collections.Generic.IEnumerable<Nest.IHit<ElasticsearchLoad.MyObject>>'
You are correct, I forgot Hits is an IEnumerable, you need to foreach over each item instead. I have updated the answer.
Does this mean the documentation is out of date, which gives this example? .Fields(p=>p.Id, p=>p.Name, p=>p.Followers.First().Name, ...) nest.azurewebsites.net/nest/search/fields.html
Yes, I believe the documentation is out of date.
3

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.