Нечувствительный к акценту запрос ElasticSearch с клиентом NEST C#

Я пытаюсь сделать запрос в ElasticSearch с клиентом NEST С# запросом без акцента, в моих данных есть португальское латинское слово с акцентом. См. код ниже:

var result = client.Search<Book>(s => s
    .From(0)
    .Size(20)
    .Fields(f => f.Title)
    .FacetTerm(f => f.OnField(of => of.Genre))
    .Query(q => q.QueryString(qs => qs.Query("sao")))
);

Этот поиск ничего не нашел. Мои данные по этому индексу содержат много заголовков, таких как: "Сан Кристован", "Сан Гонсалу".

var settings = new IndexSettings();
settings.NumberOfReplicas = 1;
settings.NumberOfShards = 5;
settings.Analysis.Analyzers.Add("snowball", new Nest.SnowballAnalyzer { Language = "Portuguese" });
var idx5 = client.CreateIndex("idx5", settings);

Как я могу сделать запрос "sao" и найти "são" с помощью ElasticSearch?

Я думаю, что нужно создать индекс с правильными свойствами, но я уже пробовал много настроек, таких как.

или в режиме Raw:


    {
     "idx" : {
       "settings" : {
         "index.analysis.filter.jus_stemmer.name" : "brazilian",
         "index.analysis.filter.jus_stop._lang_" : "brazilian"
       }
     }
    }

Как я могу сделать поиск и игнорировать акценты?

Спасибо, друзья,


person Jeferson Tenorio    schedule 02.05.2013    source источник


Ответы (3)


Смотрите решение:

Подключитесь к поиску elasticsearch с помощью putty:

curl -XPOST 'localhost:9200/idx30/_close'

curl -XPUT 'localhost:9200/idx30/_settings' -d '{
            "index.analysis.analyzer.default.filter.0": "standard",
            "index.analysis.analyzer.default.tokenizer": "standard",
            "index.analysis.analyzer.default.filter.1": "lowercase",
            "index.analysis.analyzer.default.filter.2": "stop",
            "index.analysis.analyzer.default.filter.3": "asciifolding",
            "index.number_of_replicas": "1"
}'

curl -XPOST 'localhost:9200/idx30/_open'

Замените "idx30" на имя вашего индекса.

Сделанный!

person Jeferson Tenorio    schedule 03.05.2013
comment
Можно ли восстановить настройки по умолчанию и удалить фильтры? - person RodriKing; 26.06.2018

Я наткнулся на эту тему, так как у меня такая же проблема. Вот код NEST для создания индекса с помощью анализатора AsciiFolding:

// Create the Client
string indexName = "testindex";
var uri = new Uri("http://localhost:9200");
var settings = new ConnectionSettings(uri).SetDefaultIndex(indexName);
var client = new ElasticClient(settings);
// Create new Index Settings
IndexSettings set = new IndexSettings();
// Create a Custom Analyzer ...
var an = new CustomAnalyzer();
// ... based on the standard Tokenizer
an.Tokenizer = "standard";
// ... with Filters from the StandardAnalyzer
an.Filter = new List<string>();
an.Filter.Add("standard");
an.Filter.Add("lowercase");
an.Filter.Add("stop");
// ... just adding the additional AsciiFoldingFilter at the end
an.Filter.Add("asciifolding");
// Add the Analyzer with a name
set.Analysis.Analyzers.Add("nospecialchars", an);
// Create the Index
client.CreateIndex(indexName, set);

Теперь вы можете сопоставить свою сущность с этим индексом (важно сделать это после создания индекса).

client.MapFromAttributes<TestEntity>();

А вот как может выглядеть такая сущность:

[ElasticType(Name = "TestEntity", DisableAllField = true)]
public class TestEntity
{
    public TestEntity(int id, string desc)
    {
        ID = id;
        Description = desc;
    }

    public int ID { get; set; }

    [ElasticProperty(Analyzer = "nospecialchars")]
    public string Description { get; set; }
}

Итак, поле описания теперь вставлено в указатель без акцентов. Вы можете проверить это, если проверите сопоставление вашего индекса:

http://localhost:9200/testindex/_mapping

Что тогда должно выглядеть примерно так:

{
    testindex: {
        TestEntity: {
            _all: {
                enabled: false
            },
            properties: {
                description: {
                    type: "string",
                    analyzer: "nospecialchars"
                },
                iD: {
                    type: "integer"
                }
            }
        }
    }
}

Надеюсь, это поможет кому-то.

person Roemer    schedule 28.06.2013

Вам нужно включить фильтр ACSII Folding. в свой анализатор, чтобы выполнить это. Это будет означать создание токенизаторов и фильтров формы snowballanalyzer (если только nest не позволяет добавлять фильтры к нестандартным анализаторам. ElasticSearch, насколько я знаю, этого не делает).

SnowballAnalyzer включает в себя:

  • Стандартный токенизатор
  • СтандартФильтр
  • (Добавьте сюда фильтр ASCIIFolding)
  • Нижний регистрФильтр
  • StopFilter (с соответствующим набором стоп-слов)
  • SnowballFilter (с соответствующим языком)
  • (Или, может быть, здесь)

Я бы, вероятно, попытался добавить ASCIIFoldingFilter непосредственно перед фильтром LowercaseFilter, хотя, возможно, было бы лучше добавить его в самом последнем шаге (после SnowballFilter). Попробуйте оба способа, посмотрите, какой работает лучше. Я недостаточно знаю ни о том, ни о другом стеммере на португальском языке, чтобы точно сказать, какой из них лучше.

person femtoRgon    schedule 02.05.2013
comment
Я пытался установить его, но это не работает!. settings.Analysis.Analyzers.Add(стандартный, новый Nest.StandardAnalyzer()); settings.Analysis.TokenFilters.Add(ascii, новый AsciiFoldingTokenFilter()); settings.Analysis.TokenFilters.Add(нижний регистр, новый Nest.LowercaseTokenFilter()); settings.Analysis.Analyzers.Add(lang, new Nest.LanguageAnalyzer(Language.Brazilian) { StopWords = new List‹string› { com, quem } }); settings.Analysis.Analyzers.Add(snowball, new Nest.SnowballAnalyzer {Language = Brazilian}); - person Jeferson Tenorio; 02.05.2013
comment
Вы пробовали вместо этого использовать ASCIIFoldingFilter в конце? На самом деле не уверен, что будет более подходящим. И как это не работает? Делает ли он то же самое, что и раньше, генерирует исключение, не получает результатов? - person femtoRgon; 02.05.2013