У меня есть объект ElasticSearch с этими полями:ElasticSearch C# Nest Получение лучших слов с 5.1
[Keyword]
public List<string> Tags { get; set; }
[Text]
public string Title { get; set; }
И, прежде чем я использовал, чтобы получить верхние метки, во всех документах, используя этот код:
var Match = Driver.Search<Metadata>(_ => _
.Query(Q => Q
.Term(P => P.Category, (int)Category)
&& Q.Term(P => P.Type, (int)Type))
.FielddataFields(F => F.Fields(F1 => F1.Tags, F2 => F2.Title))
.Aggregations(A => A.Terms("Tags", T => T.Field(F => F.Tags)
.Size(Limit))));
Но с Elastic 5.1, я получаю ошибку 400 с этим намеком:
Fielddata отключен текстовых полей по умолчанию. Установите fielddata = true на [Теги], чтобы загрузить полевые данные в памяти путем деинвертирования инвертированного индекса .
Тогда ES documentation about parameter mapping говорит вам «Это, как правило, не имеет смысла делать это» и «иметь текстовое поле для полнотекстового поиска, и ключевое слово непроанализированных поле с doc_values поддержкой для укрупненных».
Но единственный документ с этим значением для 5.0, и та же самая страница для 5.1, похоже, не существует.
Теперь у 5.1 есть страница о Term Aggregation, которая, кажется, покрывает то, что мне нужно, но в C#/Nest нет ничего, что я могу использовать.
Итак, я пытаюсь понять, как я могу просто получить верхние слова, во всех документах, с тегами (где каждый тег является его собственное слово, например «Нью-Йорк» не " «Новые» и «Йорк») и название (где каждое слово - это его собственная вещь) на C#.
Мне нужно отредактировать это сообщение, потому что, кажется, есть более глубокая проблема. Я написал несколько тестового кода, который иллюстрирует этот вопрос:
Давайте создадим простой объект:
public class MyObject
{
[Keyword]
public string Id { get; set; }
[Text]
public string Category { get; set; }
[Text(Fielddata = true)]
public string Keywords { get; set; }
}
создать индекс:
var Uri = new Uri(Constants.ELASTIC_CONNECTIONSTRING);
var Settings = new ConnectionSettings(Uri)
.DefaultIndex("test")
.DefaultFieldNameInferrer(_ => _)
.InferMappingFor<MyObject>(_ => _.IdProperty(P => P.Id));
var D = new ElasticClient(Settings);
заполнить индекс со случайной вещью:
for (var i = 0; i < 10; i++)
{
var O = new MyObject
{
Id = i.ToString(),
Category = (i % 2) == 0 ? "a" : "b",
Keywords = (i % 3).ToString()
};
D.Index(O);
}
и сделать запрос:
var m = D.Search<MyObject>(s => s
.Query(q => q.Term(P => P.Category, "a"))
.Source(f => f.Includes(si => si.Fields(ff => ff.Keywords)))
.Aggregations(a => a
.Terms("Keywords", t => t
.Field(f => f.Keywords)
.Size(Limit)
)
)
);
Он не может точно так же, как и раньше, с 400 и:
Fielddata отключен текстовых полей по умолчанию. Установите fielddata = true на [Keywords], чтобы загрузить полевые данные в памяти путем деинвертизации инвертированного индекса .
но Fielddata установлен на true на [Ключевые слова], но он продолжает жаловаться на это.
так, давайте сойти с ума и изменить класс таким образом:
public class MyObject
{
[Text(Fielddata = true)]
public string Id { get; set; }
[Text(Fielddata = true)]
public string Category { get; set; }
[Text(Fielddata = true)]
public string Keywords { get; set; }
}
, что, как все это текст и все имеет Fielddata = истинный .. ну, тот же результат.
так, как я на самом деле не понимая, что-то простое, или он сломан или не документированы :)
мы говорим 10million документы, примерно 500 тегов; размер, пропорциональный количеству документов или разнообразию тегов? - Было бы более разумным, чтобы я управлял этим другим путем, имея специальную таблицу для тегов и их счет? – Thomas
Как установить fielddata = true, поскольку теги [keyword], а не [text]? – Thomas
Теперь я добавил дополнительное поле только для тегов, это поле [text] с полем FieldData, установленным в true; и я все еще получаю ошибку 400, говорящую мне, чтобы установить FieldData в true в том же самом поле. Кто-нибудь использовал драйвер C# с этой функциональностью, чтобы исключить какую-либо проблему? это может быть связано: https://github.com/10up/ElasticPress/issues/643 – Thomas