在Elasticsearch Nest查询中加载特定字段

时间:2014-05-15 20:51:07

标签: elasticsearch nest

文档似乎表明我可以返回字段的子集而不是整个文档。这是我的代码:

var result = client.Search<MyObject>(s => s
                .Fields(f => f.Title)
                .Query(q => q
                    .QueryString(qs => qs
                        .OnField("title")
                        .Query("the"))));

我在“标题”字段上搜索“the”这个词,并希望只返回“标题”。我的result.Documents对象包含10个对象,每个对象都为空。

我确实看到了我想要的值,但它在搜索响应中很深入: result.Hits [0] .Fields.FieldValues [0] ...

是否有更好的方法可以获得返回的“标题”字段列表?

我的数据映射(截断)就是这个......

{
   "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"
                     }
                  }
               }                             
            }
         }
      }
   }
}

我的类对象是这样的:

[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来自我的数据源(sql),然后在索引数据之前将其解析为一个新的List对象。

2 个答案:

答案 0 :(得分:4)

我认为这个深层嵌套的值是对Elasticsearch 1.0中的更改以及现在如何将部分字段作为数组返回(有关详细信息,请参阅1.0 Breaking Changes - Return Values)。这在NEST 1.0 Breaking Changes文档中得到了解决;在 Fields()vs SourceIncludes()部分中。它显示了使用FieldValue辅助方法获取对这些值的访问权限的示例。基于此,请尝试以下方法:

对于所有项目:

 foreach (var hit in result.Hits)
 {
     var title = hit.Fields.FieldValue<MyObject, string>(f => f.Title);
 }

对于特定项目:

 var title = result.Hits.ElementAt(0)
                  .Fields.FieldValue<MyObject, string>(f => f.Title);

我知道它仍然有点冗长,但它应该适合你,并将处理Elasticsearch 1.0的新数组返回格式。

答案 1 :(得分:3)

我在Nest的Github回购中找到了解决方案。他们创造了一个关于这个问题的问题。您应该使用FielddataFields而不是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"))));

作为回应,您会看到FieldSelections。你得到了你想要的字段。