Я решил большую часть этой проблемы, теперь мне интересно, в чем проблема и что я, возможно, делаю неправильно.
Консольный запрос, который я собираюсь воссоздать с помощью NEST:
{
"tdindex" : {
"mappings" : {
"documentModel" : {
"properties" : {
"accessControl" : {
"type" : "boolean",
"copy_to" : [
"copyTo"
]
},
"comments" : {
"properties" : {
"comment" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
},
"copy_to" : [
"copyTo"
]},
"createDate" : {
"type" : "date",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
},
"copy_to" : [
"copyTo"
]},
"user" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
},
"copy_to" : [
"copyTo"
]
}
}
},
"copyTo" : {
"type" : "text"
},
"documentType" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
},
"copy_to" : [
"copyTo"
]
},
"filename" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
},
"copy_to" : [
"copyTo"
]
},
"folderID" : {
"type" : "long",
"copy_to" : [
"copyTo"
]
},
"metadata" : {
"properties" : {
"key" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
},
"copy_to" : [
"copyTo"
]
},
"value" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
},
"copy_to" : [
"copyTo"
]
}
}
},
"uploadDate" : {
"type" : "date",
"copy_to" : [
"copyTo"
]
},
"uploadUser" : {
"type" : "text",
"fields" : {
"keyword" : {
"type" : "keyword",
"ignore_above" : 256
}
},
"copy_to" : [
"copyTo"
]
}
}
}
}
}
}
В настоящее время у меня есть следующий консольный запрос, созданный в моем гнезде:
{
"mappings": {
"properties": {
"folderid": {
"copy_to": [
"CopyTo"
],
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
"filename": {
"copy_to": [
"CopyTo"
],
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
"documenttype": {
"copy_to": [
"CopyTo"
],
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
"uploaddate": {
"copy_to": [
"CopyTo"
],
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
"uploaduser": {
"copy_to": [
"CopyTo"
],
"fields": {
"keyword": {
"ignore_above": 256,
"type": "keyword"
}
},
"type": "text"
},
"comments": {
"properties": {
"createdate": {
"type": "date"
},
"comment": {
"type": "text"
},
"user": {
"type": "text"
}
},
"copy_to": [
"CopyTo"
],
"type": "nested"
},
"metadata": {
"properties": {
"key": {
"type": "text"
},
"value": {
"type": "text"
}
},
"copy_to": [
"CopyTo"
],
"type": "nested"
},
"CopyTo": {
"type": "text"
}
}
}
}
Как видите, DocumentModel не учитывается…
Я использую код NEST:
_elasticClient.CreateIndex(indexParameters.IndexName, c =>
{
c.Map<DocumentModel>(m => m
.Properties(ps => ps
.Text(t => t.Name(n => n.FolderID).CopyTo(n => n.Field(f => f.CopyTo)).Fields(fd => fd.Keyword(k => k.Name("keyword").IgnoreAbove(256))))
.Text(t => t.Name(n => n.Filename).CopyTo(n => n.Field(f => f.CopyTo)).Fields(fd => fd.Keyword(k => k.Name("keyword").IgnoreAbove(256))))
.Text(t => t.Name(n => n.DocumentType).CopyTo(n => n.Field(f => f.CopyTo)).Fields(fd => fd.Keyword(k => k.Name("keyword").IgnoreAbove(256))))
.Text(t => t.Name(n => n.UploadDate).CopyTo(n => n.Field(f => f.CopyTo)).Fields(fd => fd.Keyword(k => k.Name("keyword").IgnoreAbove(256))))
.Text(t => t.Name(n => n.uploadUser).CopyTo(n => n.Field(f => f.CopyTo)).Fields(fd => fd.Keyword(k => k.Name("keyword").IgnoreAbove(256))))
.Nested<Comments>(cm => cm.Name(n => n.Comments).AutoMap().CopyTo(n => n.Field(f => f.CopyTo)))
.Nested<Metadata>(md => md.Name(n => n.Metadata).AutoMap().CopyTo(n => n.Field(f => f.CopyTo)))
.Text(t => t.Name(n => n.CopyTo)))
Моя DocumentModel выглядит так (я не могу использовать [ElasticsearchType(Name = "documentModel")] по какой-то причине в модели, не уверен, является ли это частью причины проблемы?):
public class DocumentModel
{
[Text(Name = "filename")]
public string Filename { get; set; }
[Text(Name = "folderid")]
public int FolderID { get; set; }
[Text(Name = "uploaduser")]
public string uploadUser { get; set; }
[Date(Format = "MMddyyyy")]
public DateTime UploadDate { get; set; }
[Text(Name = "documenttype")]
public string DocumentType { get; set; }
[Boolean(NullValue = false)]
public bool AccessControl { get; set; }
[Nested]
public List<Comments> Comments { get; set; }
[Nested]
public List<Metadata> Metadata { get; set; }
[Text(Name = "CopyTo")]
public string CopyTo { get; set; }
}
public class Comments
{
[Date(Format = "MMddyyyy")]
public DateTime CreateDate { get; set; }
[Text(Name = "comment")]
public string Comment { get; set; }
[Text(Name = "user")]
public string User { get; set; }
}
public class Metadata
{
[Text(Name = "key")]
public string Key { get; set; }
[Text(Name = "value")]
public string Value { get; set; }
}
Ошибка, которую я получаю из консоли при выполнении запроса:
{
"error": {
"root_cause": [
{
"type": "mapper_parsing_exception",
"reason": "Root mapping definition has unsupported parameters: [metadata : {copy_to=[CopyTo], type=nested, properties = {value = {type=text}, key = {type=text}}}] [filename : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}] [comments : {copy_to=[CopyTo], type=nested, properties = {createdate = {type=date}, comment = {type=text}, user = {type=text}}}] [uploaddate : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}] [CopyTo : {type=text}] [documenttype : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}] [folderid : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}] [uploaduser : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}]"
}
],
"type": "mapper_parsing_exception",
"reason": "Failed to parse mapping [properties]: Root mapping definition has unsupported parameters: [metadata : {copy_to=[CopyTo], type=nested, properties = {value = {type=text}, key = {type=text}}}] [filename : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}] [comments : {copy_to=[CopyTo], type=nested, properties = {createdate = {type=date}, comment = {type=text}, user = {type=text}}}] [uploaddate : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}] [CopyTo : {type=text}] [documenttype : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}] [folderid : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}] [uploaduser : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}]",
"caused_by": {
"type": "mapper_parsing_exception",
"reason": "Root mapping definition has unsupported parameters: [metadata : {copy_to=[CopyTo], type=nested, properties = {value = {type=text}, key = {type=text}}}] [filename : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}] [comments : {copy_to=[CopyTo], type=nested, properties = {createdate = {type=date}, comment = {type=text}, user = {type=text}}}] [uploaddate : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}] [CopyTo : {type=text}] [documenttype : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}] [folderid : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}] [uploaduser : {copy_to=[CopyTo], fields = {keyword = {ignore_above=256, type=keyword}}, type=text}]"
}
},
"status": 400
Есть идеи?
Я предполагаю, что проблема связана с картой?
P.S. Я использую Kibana 6.7.1 и Elastic 6.7.1 через локальный хост. Я запускаю запрос (из объекта JSON, созданного запросом с использованием NEST)
Оказывается, я использую NEST 7.0.0-aplha... Мне удалось приблизить консольный запрос к тому, что я хочу, но все равно без радости... Я обязательно обновлю этот пост, если добьюсь каких-либо успехов ... Ваше здоровье
Пожалуйста, не меняйте полностью текст вопроса после того, как найдете решение, так как вы удаляете контекст исходного вопроса.
Я не хотел менять весь контекст. Я понял, что проблема не была конкретно рассмотрена в вопросе, и когда я отправил вопрос, я понял, что структура запроса, который я ранее разместил, была неправильной, правильный код выше делает вопрос проще, почему я получаю mapper_parsing_exception, и если я не могу использовать [ElasticsearchType(Name = "documentModel")] - это что-то, что связано с проблемой синтаксического анализа и отсутствием documentModel... если вы видели оба вопроса, зачем публиковать то, что у вас есть, никому не поможет... не пишите, если вы не можете помочь решить проблему...
Что касается отсутствующего ключа «documentModel»: ES 7.0 по умолчанию запрещает указывать тип документа, присваивая параметру запроса include_type_name значение false по умолчанию. См. elastic.co/guide/en/elasticsearch/reference/master/…. Ваша фактическая проблема, вероятно, связана с тем, как вы передаете сопоставление в Elasticsearch. Вам нужно быть более точным в том, что вы подразумеваете под «ошибкой, которую я получаю из консоли при выполнении запроса» - какую консоль? Какая конечная точка? Как вы выполняете запрос?
Я только что попробовал это на своем кластере; сопоставление, сгенерированное для вас гнездом, на самом деле правильное и создает индекс, как и ожидалось. Взгляните на примеры в elastic.co/guide/en/elasticsearch/reference/current/… и elastic.co/guide/en/elasticsearch/reference/current/…, чтобы увидеть, как вы должны отправить запрос в ES. Есть небольшая вероятность, что это гнездовой жук. re: «не публикуйте сообщения, если вы не можете помочь решить проблему»: в качестве взаимного ответа не задавайте вопрос на StackOverflow, если вы не готовы внести свой вклад в развитие сайта.
Cheers @Backgammon Я попробую еще раз и обновлю свой пост утром; что касается дальнейшего объяснения «Ошибка, которую я получаю из консоли при выполнении запроса», я запускаю Kibana 6.7.1 и Elastic 6.7.1 через локальный хост. Я запускаю запрос (из объекта JSON, созданного запросом с использованием NEST)… Как вы сказали, синтаксис кажется приемлемым (завтра мне нужно будет более внимательно посмотреть)
Глядя на ваш код (конкретно я не знаком с NEST), похоже, что вы пропускаете вызов Mappings перед Map? См., например. пример вызова createIndex на этой странице: astic.co/guide/en/elasticsearch/client/net-api/current/…
@Backgammon Я думаю, что в NEST 7.x (Elastic) он устарел, Nest теперь заявляет, что «CreateIndexDescriptor.Mapings (Func<MappingsDescriptor, <ITypeMapping>)» устарел: «Mapping больше не является словарем в 7.x, пожалуйста, используйте упрощенная карта ()…» было больно найти новый синтаксис





Для Elasticsearch 6.7.1 используйте последний клиент NEST 6.x, который на данный момент 6.7.0. Основные версии клиента совместимы с основными версиями Elasticsearch.
В NEST 6.7.0 сопоставление будет выглядеть примерно так:
private static void Main()
{
var defaultIndex = "tdindex";
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var settings = new ConnectionSettings(pool)
.DefaultIndex(defaultIndex);
var client = new ElasticClient(settings);
var visitor = new MyVisitor();
client.CreateIndex(defaultIndex, c => c
.Mappings(m => m
.Map<DocumentModel>(mm => mm
.AutoMap(visitor)
.Properties(ps => ps
.Nested<Comments>(cm => cm
.Name(n => n.Comments)
.AutoMap(visitor)
)
.Nested<Metadata>(md => md
.Name(n => n.Metadata)
.AutoMap(visitor)
)
.Text(t => t.Name(n => n.CopyTo))
)
)
)
);
}
public class MyVisitor : NoopPropertyVisitor
{
public override void Visit(ITextProperty property, PropertyInfo propertyInfo, ElasticsearchPropertyAttributeBase attribute)
{
base.Visit(property, propertyInfo, attribute);
property.CopyTo = Infer.Fields<DocumentModel>(f => f.CopyTo);
property.Fields = new Properties
{
{ "keyword", new KeywordProperty { IgnoreAbove = 256 } }
};
}
}
[ElasticsearchType(Name = "documentModel")]
public class DocumentModel
{
[Text(Name = "filename")]
public string Filename { get; set; }
[Text(Name = "folderid")]
public int FolderID { get; set; }
[Text(Name = "uploaduser")]
public string uploadUser { get; set; }
[Date(Format = "MMddyyyy")]
public DateTime UploadDate { get; set; }
[Text(Name = "documenttype")]
public string DocumentType { get; set; }
[Boolean(NullValue = false)]
public bool AccessControl { get; set; }
[Nested]
public List<Comments> Comments { get; set; }
[Nested]
public List<Metadata> Metadata { get; set; }
[Text(Name = "copyTo")]
public string CopyTo { get; set; }
}
public class Comments
{
[Date(Format = "MMddyyyy")]
public DateTime CreateDate { get; set; }
[Text(Name = "comment")]
public string Comment { get; set; }
[Text(Name = "user")]
public string User { get; set; }
}
public class Metadata
{
[Text(Name = "key")]
public string Key { get; set; }
[Text(Name = "value")]
public string Value { get; set; }
}
Поскольку все сопоставления текста, кроме свойства CopyTo, имеют ключевое слово multi_fields и copy_to для копирования в поле CopyTo, проще всего использовать определить это с посетителем. Сначала вызывается Automap(), минуя посетителя. Автоматическое сопоставление подберет сопоставления атрибутов моделей, а методы посещения посетителя позволят нам переопределить любой из них. Затем Properties() переопределит любые сопоставления из процесса автоматического сопоставления.
Окончательное выходное отображение
PUT http://localhost:9200/tdindex?pretty=true
{
"mappings": {
"documentModel": {
"properties": {
"filename": {
"type": "text",
"copy_to": [
"copyTo"
],
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"folderid": {
"type": "text",
"copy_to": [
"copyTo"
],
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"uploaduser": {
"type": "text",
"copy_to": [
"copyTo"
],
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"uploadDate": {
"type": "date",
"format": "MMddyyyy"
},
"documenttype": {
"type": "text",
"copy_to": [
"copyTo"
],
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"accessControl": {
"type": "boolean",
"null_value": false
},
"comments": {
"type": "nested",
"properties": {
"createDate": {
"type": "date",
"format": "MMddyyyy"
},
"comment": {
"type": "text",
"copy_to": [
"copyTo"
],
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"user": {
"type": "text",
"copy_to": [
"copyTo"
],
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"metadata": {
"type": "nested",
"properties": {
"key": {
"type": "text",
"copy_to": [
"copyTo"
],
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
},
"value": {
"type": "text",
"copy_to": [
"copyTo"
],
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
},
"copyTo": {
"type": "text"
}
}
}
}
}
Синтаксис NEST 7.x, совместимый с Elasticsearch 7.x, такой же; есть несколько вещей, которые устарели, чтобы изменить могу, чтобы удалить предупреждения, но синтаксис 6.x работает как есть
client.CreateIndex(defaultIndex, c => c
// remove .Mappings()
.Map<DocumentModel>(mm => mm
.AutoMap(visitor)
.Properties(ps => ps
.Nested<Comments>(cm => cm
.Name(n => n.Comments)
.AutoMap(visitor)
)
.Nested<Metadata>(md => md
.Name(n => n.Metadata)
.AutoMap(visitor)
)
.Text(t => t.Name(n => n.CopyTo))
)
)
);
// Use RelationName instead of Name
[ElasticsearchType(RelationName = "documentModel")]
public class DocumentModel
{
[Text(Name = "filename")]
public string Filename { get; set; }
[Text(Name = "folderid")]
public int FolderID { get; set; }
[Text(Name = "uploaduser")]
public string uploadUser { get; set; }
[Date(Format = "MMddyyyy")]
public DateTime UploadDate { get; set; }
[Text(Name = "documenttype")]
public string DocumentType { get; set; }
[Boolean(NullValue = false)]
public bool AccessControl { get; set; }
[Nested]
public List<Comments> Comments { get; set; }
[Nested]
public List<Metadata> Metadata { get; set; }
[Text(Name = "copyTo")]
public string CopyTo { get; set; }
}
Это именно то, что мне нужно, проблема, как и в случае с моим кодом выше (в котором я не уверен, что все это прояснил...), заключается в том, что [ElasticsearchType(Name = "documentModel")] показывает ошибку: "Тип или пространство имен «Имя» не найдено».... Я не уверен, связано ли это с использованием NEST 7.0-alpha... Какую версию NEST вы используете?
Я использую 6.7.0. Это будет связано с использованием версии 7.0.0-alpha1, которая несовместима с Elasticsearch 6.7.0.
Я попытаюсь понизить рейтинг своего NEST, я быстро вернусь с результатом
С NEST 6.7.0 код вашего решения и мой работают; при этом я хотел бы увидеть синтаксис для 7.x, если кто-нибудь его знает? На данный момент я буду придерживаться 6.7.0 и реализую класс посетителей, приветствую этого Расса, если кто-то не ответит мне с синтаксисом 7.x в ближайшее время, я дам вам ответ.
тот же синтаксис будет работать в 7.x. Есть несколько устаревших предупреждений, для исправления которых можно изменить код.
когда я использую [ElasticsearchType(Name = "documentModel")], он показывает ошибку: "Не удалось найти тип или пространство имен "Имя"". .0.
Если вы используете Elasticsearch 7.x, попробуйте 7.0.0-alpha2. Name был добавлен обратно, но устарел: github.com/elastic/elasticsearch-net/pull/3702
Я использовал ваш автомаппер с объектом посетителя, собираюсь использовать 6.7.0, пока 7.0 не выйдет за пределы альфа-ура
Какую версию Nest вы используете? Текущая версия еще не поддерживает Elastic 7, но доступна альфа-версия, если вы включите предварительные версии в Nuget. Вы можете увидеть поддерживаемые версии здесь: github.com/elastic/elasticsearch-net