Адрес электронной почты ElasticSearch со специальными символами, такими как @ - PullRequest
1 голос
/ 28 января 2020

Я использую ElasticSearch v6.8 и клиент NEST, пишу код C#. Я использую свободное отображение.

Я индексирую поле электронной почты, чтобы найти пользователей, выполнив поиск по их адресу электронной почты. Стандартный анализатор не работал, и я прочитал об использовании токенизатора uax_url_email. Я подключил его, и он работает лучше, чем стандартный анализатор, но я все еще не могу искать, используя символ @ или '.' персонаж. Пример: введите «firstname», чтобы получить совпадение. Введите «имя @» не совпадает. Введите «firstname.lastname» тоже не совпадает.

Что я делаю не так? Я предполагал, что токенизатор uax_url_email справится с этим. Вместо этого я переключился на использование NGram, и тогда он работает, но просто странно, что существующий встроенный анализатор электронной почты не обрабатывает знак @ и тому подобное.

Вот мое отображение поля (это простая строка ):

 .Map<UserSearchEntity>(
                        m => m
                            .AutoMap()
                            .Properties(p => p
                                .Text(t => t
                                    .Name(n => n.Email)
                                    .Analyzer("user_email_analyzer")))

Анализатор был зарегистрирован ранее с токенайзером uax_url_email.

1 Ответ

2 голосов
/ 28 января 2020

Вот простое приложение, показывающее использование токенайзера uax_url_email .

{
    var createIndexResponse = await client.CreateIndexAsync("my_index", c => c
        .Settings(s => s.Analysis(a => a
            .Analyzers(an => an.Custom("my_analyzer", cu => cu.Tokenizer("my_tokenizer")))
            .Tokenizers(t => t.UaxEmailUrl("my_tokenizer", u => u.MaxTokenLength(3)))))
        .Mappings(m => m
            .Map<Document>(map => map
                .Properties(p => p.Text(t => t.Name(n => n.Email).Analyzer("my_analyzer"))))));

    var indexResponse = await client.IndexAsync(new Document {Id = "1", Email = "robert.lyson@domain.com"},
        i => i.Refresh(Refresh.WaitFor));

    await Search(client, "robert.lyson");
    await Search(client, "robert");
    await Search(client, "lyson");
    await Search(client, "@domain.com");
    await Search(client, "domain.com");
    await Search(client, "rob");
}

private static async Task Search(ElasticClient client, string query)
{
    var searchResponse = await client.SearchAsync<Document>(s => s
        .Query(q => q.Match(m => m.Field(f => f.Email).Query(query))));

    System.Console.WriteLine($"result for query \"{query}\": {string.Join(",", searchResponse.Documents.Select(x => x.Email))}");
}

public class Document
{
    public string Id { get; set; }
    public string Email { get; set; }
}

output:

result for query "robert.lyson": robert.lyson@domain.com
result for query "robert": robert.lyson@domain.com
result for query "lyson": robert.lyson@domain.com
result for query "@domain.com": robert.lyson@domain.com
result for query "domain.com": robert.lyson@domain.com
result for query "rob": robert.lyson@domain.com

Протестировано с Flexiblesearch 6.8.0 и NEST 6.8. х.

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

...