Как добавить в поисковый запрос hibernate значения полей? - PullRequest
1 голос
/ 09 января 2020

У меня есть два поля в классе сущности:

  1. имя_установки
  2. contactType

contactType имеет значения например, УАТС, GSM, TEL и ФАКС

Я хочу механизм оценки, чтобы сначала получить наиболее подходящие данные, а затем УАТС, TEL, GSM и ФАКС.

Оценка:

  • Вкл. creationName , чтобы сначала получить наиболее подходящие данные
  • Вкл. contactType , чтобы получить первую АТС, затем TEL и т. Д.

Мой последний запрос:

(+ имя_установки: kamran ~ 1 ^ 2.5 + (тип контакта: УАТС ^ 2.0 тип контакта: TEL ^ 1.8 contactType: GSM ^ 1.6 contactType: FAX ^ 1.4))

Но это не возвращает результат.

Мой вопрос: как увеличить поле спецификаций c на основе разных значений?

Мы можем использовать следующий запрос для двух разных полей:

Query query = qb.keyword()
    .onField( field_one).boostedTo(2.0f)
    .andField( field_two)
    .matching( searchTerm)
    .createQuery();

Но мне нужно увеличить поле на его значения, так как в моем случае это contactType .

* 1 047 * Мой набор данных:
(название заведения: украшение концерта, contactType: GSM), (имя заведения: концерт Elissa, contactType: TEL), (имя учреждения: концерт Yara, contactType: FAX), (имя учреждения: E Concept, contactType: TEL), (учреждение Name: Infinity Concept, contactType: FAX), (учреждение Name: SD Concept, contactType: PBX), (учреждение Name: Broadcom Technical Concept, contactType: GSM), (учреждение Name: Concept Businessmen, contactType: УАТС)

При поиске термина = концерт (нечеткий запрос по заведению) он должен вернуть мне список, приведенный ниже: (учреждение: имя: концерт Elissa, contactType: TEL)

[термин = концерт, точное совпадение, поэтому он будет на вершине, сохраняя порядок в качестве УАТС, ТЕЛ, GSM и ФАКС]

(учреждениеИмя: оформление концерта, тип контакта: GSM)

[термин = концерт, точное соответствие и при сохранении заказа в виде УАТС, ТЕЛ, GSM и ФАКС]

* 106 6 * (имя учреждения: Yara Concert, contactType: FAX)

[термин = концерт, точное соответствие и при сохранении заказа в виде УАТС, ТЕЛ, GSM и ФАКС]

(имя-учреждения: Concept Businessmen, contactType: PBX)

[термин = концерт, частичное совпадение и сохранение заказа в виде УАТС, ТЕЛ, GSM и ФАКС]

( имя_установки: SD Concept, contactType: PBX)

[термин = согласование, частичное сопоставление и сохранение порядка в качестве УАТС, ТЕЛ, GSM и ФАКС]

(имя_установки: E Concept, contactType: TEL)

[термин = согласование, частичное сопоставление и сохранение порядка в качестве УАТС, TEL, GSM и факса]

(название учреждения: Broadcom Technical Concept, contactType: GSM)

[термин = концерт, частичное совпадение и сохранение порядка в качестве УАТС, ТЕЛ, GSM и ФАКС]

(учреждение Имя: Концепция Бесконечности, contactType: FAX)

[термин = концерт, частичное совпадение и kee проверить заказ как АТС, ТЕЛ, GSM и ФАКС]

1 Ответ

1 голос
/ 13 января 2020

Из того, что я понимаю, вы в основном хотите двухфазную сортировку:

  1. Поместите точные совпадения перед другими (нечеткими) совпадениями.
  2. Сортируйте по типу контакта.

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

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

Вместо этого:

Query query = qb.keyword()
    .fuzzy().withEditDistanceUpTo(1)
    .boostedTo(2.5f)
    .onField("establishmentName")
    .matching(searchTerm)
    .createQuery();

Сделайте это:

Query query = qb.bool()
    .should(qb.keyword()
        .withConstantScore().boostedTo(100.0f) // Higher score, sort first
        .onField("establishmentName")
        .matching(searchTerm)
        .createQuery())
    .should(qb.keyword()
        .fuzzy().withEditDistanceUpTo(1)
        .withConstantScore().boostedTo(1.0f) // Lower score, sort last
        .onField("establishmentName")
        .matching(searchTerm)
        .createQuery())
    .createQuery();

Соответствующие документы будут такими же, , но , теперь запрос будет назначать предсказуемые оценки: 1,0 для нечетких совпадений и 101.0 (1 из нечеткого запроса и 100 из точного запроса) для точных совпадений.

Таким образом, вы можете определить сортировку следующим образом:

fullTextQuery.setSort(qb.sort()
    .byScore()
    .andByField("contactType")
    .createSort());

Это может не быть очень элегантное или оптимизированное решение, но я думаю, что оно будет работать.

Чтобы настроить относительный порядок типов контактов, я бы предложил другой подход: использовать пользовательский мост для индексирования чисел вместо «УАТС» / «ТЕЛ» / et c. назначьте каждому типу контакта порядковый номер, который вы ожидаете. По сути, что-то вроде этого:

public class Establishment {

@Field(name = "contactType_sort", bridge = @FieldBridge(impl = ContactTypeOrdinalBridge.class))
private ContactType contactType;

}

public class ContactTypeOrdinalBridge implements MetadataProvidingFieldBridge {

    @Override
    public void set(String name, Object value, Document document, LuceneOptions luceneOptions) {
        if ( value != null ) {
          int ordinal = getOrdinal((ContactType) value);
          luceneOptions.addNumericFieldToDocument(name, ordinal, document);
          luceneOptions.addNumericDocValuesFieldToDocument(name, ordinal, document);
        }
    }


    @Override
    public void configureFieldMetadata(String name, FieldMetadataBuilder builder) {
        builder.field(name, FieldType.INTEGER).sortable(true);
    }

    private int getOrdinal(ContactType value) {
        switch( value ) {
          case PBX: return 0;
          case TEL: return 1;
          case GSM: return 2;
          case PBX: return 3;
          default: return 4;
        }
    }
}

Затем переиндексируйте и сортируйте так:

fullTextQuery.setSort(qb.sort()
    .byScore()
    .andByField("contactType_sort")
    .createSort());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...