elasticsearch,asp.net-web-api,nest,C#,elasticsearch,Asp.net Web Api,Nest" /> elasticsearch,asp.net-web-api,nest,C#,elasticsearch,Asp.net Web Api,Nest" />

C# 使用嵌套索引动态对象

C# 使用嵌套索引动态对象,c#,elasticsearch,asp.net-web-api,nest,C#,elasticsearch,Asp.net Web Api,Nest,我正在构建一个API应用程序,它本质上允许用户构建一个文档,该文档可以按照他们想要的方式构造,并存储在Elasticsearch中。本质上,我为用户提供了一个简单的界面来访问我们的Elasticsearch实例。我试图使实现尽可能简单。以下是我目前正在处理的问题 预期主体的对象: public class DocumentModel { public string Index { get; set; } public string Type { get; set; } p

我正在构建一个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<Uri> { 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);
}
[HttpPost]
[路线(“”)
公共IHttpActionResult帖子(文档模型文档)
{
Uri节点位置=新Uri(“http://localhost:9200");
IConnectionPool connectionPool=新嗅探连接池(新列表{nodeLocation});
ConnectionSettings设置=新的ConnectionSettings(connectionPool);
ElasticClient esClient=新的ElasticClient(设置);
IIndexResponse结果=esClient.Index(文档,i=>i
.Index(document.Index)
.Type(document.Type)
.Id(document.Id));
返回Ok(result.IsValid);
}
这很好,但它包括源中的索引、类型和Id。我真正想做的是在索引时提供这三条信息,但实际上只是索引document.document,这是一种动态类型。但是,这似乎与Nest不符,因为它在IDE和编译时抛出了一个错误:

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

“如果不首先将lambda表达式强制转换为委托或表达式树类型,则无法将其用作动态调度操作的参数”


我怎样才能为文档编制索引。文档?有没有比使用动态类型更好的方法来处理未知结构的传入JSON文档?

有几种方法可以做到这一点

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

dynamicDoc=new{/*此处填写文档格式*/};
ElasticClient esClient=新的ElasticClient(esSettings);
IndexRequest request=新IndexRequest(dynamicDoc)
{
Index=“someindex”,
Type=“SomeType”,
Id=“someid”
};
客户索引(请求);
或者如果处理大量的文件

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);
列表文档=新列表();
//填充文档
BulkDescriptor描述符=新的BulkDescriptor();
foreach(文档中的var文档)
{
descriptor.Index(i=>i
.Index(“someindex”)
.Type(“SomeType”)
.Id(“someid”)
.文件(doc));
}
esClient.Bulk(描述符);
NEST(或者更准确地说,Elasticsearch.Net)还有一个.Raw方法变量附加到ElasticClient类,它可以索引原始JSON。使用Raw.Index()让我们执行以下操作:

string documentJson = JsonConvert.SerializeObject(document.Document);

ElasticsearchResponse<string> result = esClient.Raw.Index(document.Index, document.Type, document.Id, documentJson);
string documentJson=JsonConvert.serialized对象(document.document);
ElasticsearchResponse结果=esClient.Raw.Index(document.Index,document.Type,document.Id,documentJson);

响应的类型描述符是您期望响应所处的类型(字符串表示您将有一个序列化的json响应,您可以对其进行反序列化和处理)。这使我们能够避开整个对象类型问题,并完全按照预期将文档的索引嵌套到Elasticsearch中。

我希望是原始的。索引保留了新索引中旧索引的父子关系,而不是
动态的
我使用过
字典
或从类继承的。警告:如果从
字典继承,嵌套将不会自动映射文档上的其他属性(将它们放在字典中)。这也适用于变量属性:公共属性进入POCO属性,变量属性进入
数据
属性(使用类型
字典
)。这种批量方法易于使用。不要忘记获取调用
批量检查
的结果。错误
等!由
dynamic document=JsonConvert.DeserializeObject(jsonString)转换的动态类型将无法直接工作。这是解决方案,NEST.JsonNetSerializer是解决方案。这就是如何实现
string documentJson = JsonConvert.SerializeObject(document.Document);

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