Регистронезависимый поля в Elasticsearch

Я использую NEST с ElasticSearch, и я пытаюсь найти, позволяя пользователям вводить поисковые фразы в поле поиска. Все работает нормально, кроме того, когда пользователь вводит поисковую фразу, Им нужно убедиться, что имя поля совпадает с именем Поля в эластичном поиске.

например, одно из моих полей называется bookTitle. Если они ищут, как показано ниже, то это работает

bookTitle:"Сказка о двух городах"

если они ищут, как пример ниже не работает

booktitle: "Сказка о двух городах" BookTitle:"Сказка о двух городах"

код, который я использую для поиска, приведен ниже. У кого-нибудь есть идеи, как я могу это исправить. Я надеялся, что есть настройка ElasticSearch/NEST, которая позволяет мне делать это, а не делать что-то уродливое с текстом поиска, таким как поиск "BookTitle" и замена на "bookTitle".

   public List<ElasticSearchRecord> Search(string searchterm) {

        var results = _client.Search<ElasticSearchRecord>(s => s
                        .Query(q => q
                            .QueryString(qs => qs
                                .DefaultField("content")
                                .Query(searchterm)
                            )
                        ));


        return results.Documents.ToList();
    }

любая помощь очень ценится.

3 ответов


то, как вы хотите, это невозможно с Elasticsearch. Вы контролируете отображение, вы определяете имена полей, вы тот, кто контролирует запросы.

по этому мнению, вам нужно следить за тем, что ваши пользователи будут вводить в поле поиска, Elasticsearch out-of-the-box не поможет вам с именами полей в нижнем регистре или что-то в этом роде.

Итак, какое бы решение вы ни выбрали, это будет обходной путь.

мой предложение определите набор правил, это также должно быть сообщено вашим пользователям. Что-то вокруг этих строк:

  • ваши имена полей все строчные, или стиле Camel
  • вы определяете отображение как strict Так что вы находитесь в полном контроле над ним
  • вы уведомляете пользователей (в веб-интерфейсе или пользовательском интерфейсе), что они должны искать имена полей с заданным набором правил (только в нижнем регистре или только в случае верблюда и т. д.)

другой подход заключается в определении что входит в _all поле. И в вашем QueryString вы не используете конкретные имена полей, и ES будет использовать query_string по умолчанию. Это означает, что ES будет использовать _all, an


вы можете кэшировать отображение в C# в памяти и подтвердить, что все поля поиска найдены из него. Если точное совпадение не найдено, попробуйте найти наиболее подходящие поля. Если есть несколько вариантов на выбор, то бросьте ошибку и попросите пользователя быть более конкретным.

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


еще не протестировали это как качество производства, но теоретически вы можете сохранить все свои объекты с помощью стратегии именования в нижнем регистре .ToLower () ваши запрашиваемые поля, чтобы они всегда совпадали.

Начнем с создания соответствующей стратегии именования:

public class LowercaseNamingStrategy : Newtonsoft.Json.Serialization.NamingStrategy
{
    protected override string ResolvePropertyName(string name)
    {
        return name.ToLower();
    }
}

и соответствующий сериализатор:

    public class ElasticSerializer : JsonNetSerializer
    {
        public ElasticSerializer(IConnectionSettingsValues settings)
            : base(settings)
        {
            this.ContractResolver.NamingStrategy = new LowercaseNamingStrategy();
        }
    }

затем используйте сериализатор в настройках подключения вашего клиента NEST:

        var pool = new StaticConnectionPool([your nodes]);
        var settings = new ConnectionSettings(pool, s => new ElasticSerializer(s));
        var client = new ElasticClient(settings);

это сохранит ваши поля в нижнем регистре. Затем когда вы запрашиваете, просто заставьте все предоставленные пользователем поля быть строчными, и все должно выстраиваться.

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