使用NEST索引动态对象

 烛光一米_530 发布于 2022-12-13 09:54

我正在构建一个API应用程序,它基本上允许用户构建一个文档,该文档可以根据需要进行结构化,并存储在Elasticsearch中.从本质上讲,我为用户提供了一个简单的界面来访问我们的Elasticsearch实例.我正在努力使实现尽可能简单.这是我到目前为止所处理的问题.

预期身体的对象:

public class DocumentModel
{
    public string Index { get; set; }
    public string Type { get; set; }
    public string Id { get; set; }
    [ElasticProperty(Type = FieldType.Nested)]
    public dynamic Document { get; set; }
}

简单实施:

[HttpPost]
[Route("")]
public IHttpActionResult Post(DocumentModel document)
{
    Uri nodeLocation = new Uri("http://localhost:9200");
    IConnectionPool connectionPool = new SniffingConnectionPool(new List { nodeLocation });
    ConnectionSettings settings = new ConnectionSettings(connectionPool);
    ElasticClient esClient = new ElasticClient(settings);

    IIndexResponse result = esClient.Index(document, i => i
        .Index(document.Index)
        .Type(document.Type)
        .Id(document.Id));

    return Ok(result.IsValid);
}

这样可以正常工作,但它包含源中的索引,类型和ID.我真正想做的只是在索引时提供这三条信息,但实际上只是索引document.Document,它是动态类型.但是,这似乎与Nest不同意,因为它在IDE和编译时抛出错误:

"匿名函数或方法组不能用作动态绑定操作的组成值"

"不能将lambda表达式用作动态调度操作的参数,而无需先将其转换为委托或表达式树类型".

我怎么能索引document.Document?有没有比使用动态类型更好的方法来处理未知结构的传入JSON文档?

1 个回答
  • 有几种方法可以做到这一点.

    尝试将文档索引为动态类型将不起作用,但您可以通过IndexRequest对象将其索引为对象.

    dynamic dynamicDoc = new { /*fill in document format here*/ };
    ElasticClient esClient = new ElasticClient(esSettings);
    
    IndexRequest<object> request = new IndexRequest<object>(dynamicDoc)
    {
        Index = "someindex",
        Type = "SomeType",
        Id = "someid"
    };
    
    esClient.Index<object>(request);
    

    或者如果批量处理文件

    List<dynamic> Documents = new List<dynamic>();
    //Populate Documents
    
    BulkDescriptor descriptor = new BulkDescriptor();
    foreach(var doc in Documents)
    {
        descriptor.Index<object>(i => i
            .Index("someindex")
            .Type("SomeType")
            .Id("someid")
            .Document(doc));
    }
    
    esClient.Bulk(descriptor);
    

    NEST(或更准确地说,Elasticsearch.Net)还有一个附加到ElasticClient类的.Raw方法变体,它可以索引原始JSON.使用Raw.Index()让我们做这样的事情:

    string documentJson = JsonConvert.SerializeObject(document.Document);
    
    ElasticsearchResponse<string> result = esClient.Raw.Index(document.Index, document.Type, document.Id, documentJson);
    

    响应的类型描述符是您期望响应的类型(字符串意味着您将具有序列化的json响应,您可以反序列化并执行某些操作).这允许我们回避整个对象类型问题,并且NEST将文档完全按预期索引到Elasticsearch中.

    2022-12-13 09:58 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有