【问题标题】:How to Get a typed DTO with only some fields from Elasticsearch with Nest?如何使用 Nest 从 Elasticsearch 中获取仅包含某些字段的类型化 DTO?
【发布时间】:2016-01-13 17:10:45
【问题描述】:

我正在尝试使用 NEST 1.7.1 Get 来自 Elasticsearch 1.7.0 的结果。我的文档包含许多字段,但我只对其中一个感兴趣。我希望得到一个代表部分文档的类型化结果。

我正在使用与这段代码类似的东西:

var settings = new ConnectionSettings(new Uri(url)).SetDefaultIndex("MyIndex");
var client = new ElasticClient(settings);

var result = client.Get<MyDtoPartial>(g => g
    .Type("myDocType")
    .Id("abcdefg123456")
    .Fields("doc.subids")
);

MyDtoPartial 目前看起来像这样:

public class MyDtoPartial
{
    [JsonProperty("doc.subids")]
    public IList<string> SubIds { get; set; }

    // Other properties of my documents are not mapped, in this
    // context I only want the SubIds.
}

在调试器中,我可以深入到 result.Fields 并看到该字典中的第一个具有由调试器按照以下行呈现的值:

{[doc.subids, [ "12354adsf-123fasd", "2134fa34a-213123" ...

我还可以看到发出的 Elasticsearch 请求,是这样的:

http://myserver:12345/MyIndex/myDocType/abcdefg123456?fields=doc.subids    

它返回这种类型的json:

{
    "_index": "MyIndex",
    "_type": "myDocType",
    "_id": "abcdefg123456",
    "_version": 1,
    "found": true,
    "fields": {
        "doc.subids": ["12354adsf-123fasd",
        "2134fa34a-213123",
        "adfasdfew324-asd"]
     }
}

所以我觉得我的请求没问题,因为这我期望的那种响应。

但是,我的目标是获得一个具有完全填充的SubIds 属性的MyDtoPartial 实例。但是,result 似乎不包含任何类型的 MyDtoPartial 类型的属性。

我已经通过the Nest Get docs,实际上导致了上面的代码。

Get 一个正确类型的单个文档的正确方法是什么,只有来自 Elastic with Nest 的一些字段?

【问题讨论】:

    标签: c# elasticsearch nest


    【解决方案1】:

    如果你提到.Fields(...)Source 将永远是null。如果您删除.Fields(...),那么Source 应该是MyDtoPartial 类型并为您提供所需的结果。您仍然得到Sourcenull 的原因可能是因为在myDocType 的映射中,_source 字段被禁用。通过执行GET &lt;index name&gt;/_mapping/myDocType 检查myDocType 的定义。如果_source 被禁用,Nest 将无法在其对该类型的响应中为您提供MyDtoPartial 的具体对象。

    如果您启用了_source 但只想获取字段的子集,那么您可以使用source filtering 而不是fields 来指定您想要哪些字段以及您不想在回应。

    var result = client.Get<MyDtoPartial>(g => g
        .Type("myDocType")
        .Id("abcdefg123456")
        .SourceInclude("doc.subids")
    );
    

    现在result.Source 将成为MyDtoPartial 的对象,其中除SubIds 之外的所有字段都将为nullSubIds 将具有预期值。

    【讨论】:

    • 抱歉,我不小心把注意力集中在Source 上,可能是因为缺乏对 Elastic 的理解。我不是意味着 获取整个源,我意味着 只获取某些字段。所以我不想删除Fields(...),我这样做只是为了测试。我会尝试相应地更新我的问题。
    • 如果你提到.Fields(...),AFAIK,你没有办法得到MyDto的对象;你必须自己解析result.Fields
    • 但是您是否启用了_source?如果你这样做了,那么我可以详细说明另一个选项,这样你就不需要解析 result.Fields
    • 是的,我想是的,如果我执行GET MyIndex/_mapping/docType 我看到_source 设置为compressed,如果我使用我们的head 插件进行查询这些文档我确实看到了一个"_source",其中包含我的所有字段,包括我要检索的那个。 (它相当大,这就是为什么我不想在没有必要的情况下查询整个文档。)
    • 感谢您的广泛帮助,并接受我有点变色龙的问题。 SourceInclude 方法确实有排序效果,尽管我的属性尚未填充。但是,我怀疑这可能是从我的真实场景到我的 SO 问题的翻译过程中丢失的结果。我将不得不更深入地研究(并可能创建一个真正的复制品)以了解这将如何适用于我的实际场景。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    相关资源
    最近更新 更多