Необходимо знать, как искать в ES, используя поиск С# в массивах
Здравствуйте, я новичок в ElasticSearch
и мне нужна помощь. Я работаю с С# (думал, что могу использовать QueryRaw
в String, я думаю...).
Ниже сценария:
Данные
{
"id": "1",
"title": "Small cars",
"tagsColours": ["grey",
"black",
"white"],
"tagsCars": ["Suzuki",
"Ford"],
"tagsKeywords": []
},
{
"id": "2",
"title": "Medium cars",
"tagsColours": [],
"tagsCars": ["VW",
"Audi",
"Peugeot"],
"tagsKeywords": ["Sedan"]
},
{
"id": "3",
"title": "Big cars",
"tagsColours": ["red",
"black"],
"tagsCars": ["Jeep",
"Dodge"],
"tagsKeywords": ["Van",
"Big"]
}
Цель
Id 'нравится применять фильтры в столбцах тегов на основе выбора пользователей. значения будут заполнены в столбцах массива tagsXXX с выбранными значениями.
- Если значение параметра массива не пусто, тогда результат должен содержать хотя бы один экземпляр. То же самое для каждого массива параметров. чем больше параметры имеют значения, тем более конкретный поиск должен выполняться.
- если по крайней мере есть одно значение, исходящее из параметра, который совпадает со всеми значениями в любом столбце массива тегов документа, затем получите этот документ.
но если есть другое значение в другом массиве tagsXXX, тогда оно должно учитывать это.
- если массив параметров тега не имеет значений, тогда игнорируйте этот фильтр
Желаемые ответы
A) Если пользователь выбирает только 1 тег Color (i.e = black), как указано ниже:
{
id: "",
title: "",
tagsColours: ["black"],
tagsCars: [],
tagsKeywords: []
}
Я хотел бы получить документы с Id = 2 и id = 3, так как они имеют черный цвет в своих тегахColours и игнорировать тегиCars и tagsKeywords, так как нет значений параметров
B) Если пользователь выбирает только 2 тега diff (i.e = color = black и cars = audi и mercedez benz), как указано ниже:
{
id: "",
title: "",
tagsColours: ["black",
"yellow"],
tagsCars: ["Audi",
"Mercedes Benz"],
tagsKeywords: []
}
Я хотел бы получить документы с id = 2, так как он нашел черное на tagsColours, и он нашел Audi в тегах Car, и он не должен тянуть документ id = 1, потому что
даже когда черный находится на тегах Colours, ни одно из значений параметров (audi, mercedez benz) не находится на его знаках. Значения цен
Привет всем, у меня возникают проблемы при поиске в ElasticSearch и поиск в массивах со значениями, а когда параметры не имеют значений.
Если бы кто-нибудь мог мне помочь, я бы оценил.
Я сделал это:
termsQuery = Query<StructuredData>.Terms(t => t.Field(f =>f.TagsColours).Terms(dataToSearch.TagsColours));
termsQuery = termsQuery && Query<StructuredData>.Terms(t => t.Field(f =>f.TagsCars).Terms(dataToSearch.TagsCars));
и я остановился здесь (не добавлял третий фильтр), потому что я не мог смешивать два фильтра вместе
dataToSearch имеет значения из параметров (тот же структурный объект, причина.Поиск заставляет меня сделать это здесь .Search()
var settings = new ConnectionSettings(node);
var response = new ElasticClient(settings)
.Search<StructuredData>(
s => s.AllIndices()
.AllTypes()
.From(0)
.Size(50)
.Query(_ => termsQuery)
);
Но у меня проблемы при использовании более одного фильтра.
есть идеи? это ".Terms" правильное свойство?
Ответы
Ответ 1
Если вы используете регулярные сопоставления на ES 5 > Это даст вам результаты, которые вы хотите. Если нет, вам нужно будет изменить отображение.
QueryContainer query = null;
if(dataToSearch.TagsColours != null && dataToSearch.TagsCars.Length > 0)
{
query = Query<StructuredData>.Terms(t=>t.Field("tagsColours.keyword").Terms(dataToSearch.TagsColours));
}
if(dataToSearch.TagsColours != null && dataToSearch.TagsCars.Length > 0)
{
var q = Query<StructuredData>.Terms(t=>t.Field("tagsCars.keyword").Terms(dataToSearch.TagsCars));
query = query == null ? q : query && q;
}
if(dataToSearch.TagsKeywords != null && dataToSearch.TagsKeywords.Length > 0)
{
var q = Query<StructuredData>.Terms(t=>t.Field("tagsKeywords.keyword").Terms(dataToSearch.TagsKeywords));
query = query == null ? q : query && q;
}
Проблема, с которой вы сталкиваетесь, заключается в том, что термин "запрос" выполняется по незанятому значению, а текстовые поля по умолчанию используют стандартный анализатор. По состоянию на 5 они добавили ключевое слово sub, которое использует анализатор ключевых слов, по сути, просто помещает термины как есть, и вы можете выполнять поиск по необработанным значениям. Стандартный токенизатор анализатора для слов и нижний регистр всех терминов, поэтому он не смог найти Ауди, потому что термин был audi. Если вы хотите просто ввести строчную строку ввода, это не решит проблему Mercedes Benz, так как в стандартных условиях это станет mercedes бензином терминов два срока вместо одного, другими словами, условия вернут результаты, если вы поместите mercedes или benz, но не mercedes бенз. Если вы хотите, чтобы в случае нечувствительного к регистру поиска с запросом соответствия вам нужно было добавить пользовательский анализатор.