gpt4 book ai didi

c# - ElasticSearch - 使用 NEST 5.x 在嵌套 List 中添加元素

转载 作者:行者123 更新时间:2023-11-30 23:15:04 25 4
gpt4 key购买 nike

我的 ElasticSearch 索引中有一个列表。如何使用 NEST 2 将新元素添加到列表中?我已经搜索了我的问题的答案,但我找到的都是 answer for the version 1.x ,它对我不起作用。

型号:

public class TicketModel
{
public Guid Id { get; set; }
public Guid IdUser { get; set; }
public Guid IdAuthor { get; set; }
public Guid? IdAssignedUser { get; set; }
public Guid? IdAsset { get; set; }
public Guid? IdOwner { get; set; }
public DateTime CreationDate { get; set; }
public DateTime? ClosingDate { get; set; }
public DateTime? DueDate { get; set; }
public DateTime? LastDateUserView { get; set; }
public DateTime? LastDateAssignedUserView { get; set; }
public string TicketCode { get; set; }
public string Title { get; set; }
public int IdCategory { get; set; }
public int? IdSubcategory { get; set; }
public short? IdPriority { get; set; }
public short IdState { get; set; }
public bool IsNew { get; set; }

public List<TicketMessageModel> TicketMessageList { get; set; }
}

public class TicketMessageModel
{
public Guid Id { get; set; }
public Guid IdTicket { get; set; }
public Guid IdUserFrom { get; set; }
public Guid? IdUserTo { get; set; }
public DateTime? CreationDate { get; set; }
public DateTime? DeleteDate { get; set; }
public string Message { get; set; }
public bool HideToFinalUser { get; set; }
public byte? MessageType { get; set; }

public List<TicketMessageFilesModel> MessageFileList { get; set; }
}

public class TicketMessageFilesModel
{
public Guid Id { get; set; }
public Guid? IdTicketMessage { get; set; }
public string FileName { get; set; }
public string FileTitle { get; set; }
public string FileOriginalName { get; set; }
public byte FileType { get; set; }
}

我试图使用其他答案找到出路,但我被困在这里:

client.Update<ElasticSearchTickets.TicketMessageModel, object>(new DocumentPath<ElasticSearchTickets.TicketMessageModel>(elem.Id), 
q => q.Script(x => x.Inline("ctx._source.MessageFileList += elem"))./*??*/);

提前致谢。

编辑:

这是我试图在我的列表中插入一个新元素的代码:

ElasticSearchTickets.TicketMessageModel elem = new ElasticSearchTickets.TicketMessageModel()
{
CreationDate = message.CreationDate,
DeleteDate = message.DeleteDate,
HideToFinalUser = message.HideToFinalUser,
Id = message.Id,
IdTicket = message.IdTicket,
IdUserFrom = message.IdUserFrom,
IdUserTo = message.IdUserTo,
Message = message.Message,
MessageType = message.MessageType,
MessageFileList = tempList
};
var response = client.Update<ElasticSearchTickets.TicketModel, object>(new DocumentPath<ElasticSearchTickets.TicketModel>(elem.IdTicket.ToString()), q => q
.Script(s => s
.Inline("if (ctx._source.TicketMessageList == null) { ctx._source.TicketMessageList = element; } else { ctx._source.TicketMessageList += element; }")
.Params(d => d.Add("element", new [] { elem }))
));

但是现在我得到了一个服务器错误,因为属性“element”还没有声明。如何解决这个问题?

这是映射:

"mappings": {
"ticket": {
"properties": {
"ClosingDate": {
"type": "date"
},
"CreationDate": {
"type": "date"
},
"DueDate": {
"type": "date"
},
"Id": {
"type": "keyword"
},
"IdAsset": {
"type": "keyword"
},
"IdAssignedUser": {
"type": "keyword"
},
"IdAuthor": {
"type": "keyword"
},
"IdCategory": {
"type": "integer"
},
"IdOwner": {
"type": "keyword"
},
"IdPriority": {
"type": "short"
},
"IdState": {
"type": "short"
},
"IdSubcategory": {
"type": "integer"
},
"IdUser": {
"type": "keyword"
},
"IsNew": {
"type": "boolean"
},
"LastDateAssignedUserView": {
"type": "date"
},
"LastDateUserView": {
"type": "date"
},
"TicketCode": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"TicketMessageList": {
"type": "nested",
"properties": {
"CreationDate": {
"type": "date"
},
"DeleteDate": {
"type": "date"
},
"HideToFinalUser": {
"type": "boolean"
},
"Id": {
"type": "keyword"
},
"IdTicket": {
"type": "keyword"
},
"IdUserFrom": {
"type": "keyword"
},
"IdUserTo": {
"type": "keyword"
},
"Message": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"MessageFileList": {
"properties": {
"FileName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"FileOriginalName": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"FileTitle": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"FileType": {
"type": "short"
},
"Id": {
"type": "keyword"
},
"IdTicketMessage": {
"type": "keyword"
}
}
},
"MessageType": {
"type": "short"
}
}
},
"Title": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}

最佳答案

这是一个精简的例子

void Main()
{
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var defaultIndex = "default-index";
var connectionSettings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);

var client = new ElasticClient(connectionSettings);

if (client.IndexExists(defaultIndex).Exists)
client.DeleteIndex(defaultIndex);

client.CreateIndex(defaultIndex, c => c
.Mappings(ms => ms
.Map<TicketMessageModel>(m => m
.AutoMap()
.Properties(p => p
.Nested<TicketMessageFilesModel>(n => n
.Name(nn => nn.MessageFileList)
.AutoMap()
)
)
)
)
);

var id = "ticketmessage";

client.Index(new TicketMessageModel
{
Id = id,
MessageFileList = new List<UserQuery.TicketMessageFilesModel>
{
new TicketMessageFilesModel { Id = "file1" }
}
});

client.Update<TicketMessageModel, object>(id, q => q
.Script("if (ctx._source.messageFileList == null) { ctx._source.messageFileList = elem; } else { ctx._source.messageFileList += elem; }")
.Params(d => d
.Add("elem", new[] { new TicketMessageFilesModel { Id = "file2" } })
)
);

var getResponse = client.Get<TicketMessageModel>(id);
}

public class TicketMessageModel
{
public string Id { get; set; }
public List<TicketMessageFilesModel> MessageFileList { get; set; }
}

public class TicketMessageFilesModel
{
public string Id { get; set; }
}

getResponse JSON 响应是

{
"_index" : "default-index",
"_type" : "ticketmessagemodel",
"_id" : "ticketmessage",
"_version" : 2,
"found" : true,
"_source" : {
"id" : "ticketmessage",
"messageFileList" : [ {
"id" : "file1"
}, {
"id" : "file2"
} ]
}
}

一些兴趣点:

  1. 您需要通过检查列表是否为空来处理列表中可能没有任何项目的情况
  2. 为了追加到列表中,您需要将要追加的项目包装在一个数组中,这样列表和数组就可以追加在一起。
  3. 您需要使用 _source 中存在的序列化字段名称。默认情况下,NEST camel 在序列化为 Elasticsearch 中的字段名称时使用 POCO 属性名称

编辑:

看起来您正在使用 NEST 5.x 来对抗 Elasticsearch 5.x; 5.x 中的默认脚本语言是 Painless 而不是 2.x 中的 Groovy,因此必须对脚本进行一些细微的差别。

这是一个可以在 5.x 上使用 Painless 的版本

client.Update<TicketMessageModel, object>(id, q => q
.Script(s => s
.Inline("if (ctx._source.messageFileList == null) { ctx._source.messageFileList = new ArrayList(); } ctx._source.messageFileList.add(params.elem);")
.Params(d => d
.Add("elem", new TicketMessageFilesModel { Id = "file2" })
)
)
);

查看 guide on Painless更多细节。您也可以通过在 .Script() 中指定 .Lang("groovy") 来使用 Groovy 的原始示例,但您还需要允许内联 Groovy 脚本通过添加运行

script.engine.groovy.inline: true

到 Elasticsearch.yml 配置。 Groovy scripts are disabled by default for security reasons.

关于c# - ElasticSearch - 使用 NEST 5.x 在嵌套 List<T> 中添加元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42787404/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com