Проверьте поле поиска объекта на основе индексации - PullRequest
0 голосов
/ 18 апреля 2019

У меня есть объект, определенный следующим образом.

public class Deal {
    @Id
    @DocumentId
    @Column(name = "ID")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Field
    @Column(name = "NAME")
    private String name;

    @Field
    @Column(name = "ADVERTISER_NAME")
    private String advertiserName;

    @Field
    @Column(name = "BRAND_NAME")
    private String brandName;

    //other fields and getters/setters omitted for brevity
}

Если я хочу выполнить поиск по всем доступным для поиска полям, я могу сделать что-то вроде следующего, которое демонстрирует использование onField, onFields и andFields.


Query luceneQuery1 = mythQB
    .simpleQueryString()
    .onFields("name", "history", "description")
    .matching("teststring")
    .createQuery();


Query luceneQuery2 = mythQB
    .simpleQueryString()
    .onField("name")
        .boostedTo(5f)
    .andFields("advertiserName", "brandName")
        .boostedTo(2f)
    .withAndAsDefaultOperator()
    .matching("teststring")
    .createQuery();

Если я добавлю Index.NO в @Field (например, сделав поле сущности недоступным для поиска), поменяю аннотацию brandName на @Field (index = Index.NO), теперь у меня есть толькодва поля для поиска: name и advertiserName, если мы не рассматриваем id.В этом случае в приведенном выше примере запроса будет сгенерировано исключение во время выполнения, поскольку он пытается выполнить поиск по brandName, который не доступен для поиска.

Я пытался что-то вроде следующего, чтобы динамически получить полный список доступных для поиска полей в зависимости от того, имеет ли поле аннотацию или нет.Но это не будет работать, если индекс Index.NO.

Мой вопрос заключается в том, существует ли способ динамически получать полный список доступных для поиска полей на основе фактического значения индекса?

    protected String[] getSearchableFields() {
        List<String> fields = Lists.newArrayList();
        Class<?> c = clazz;
        while (c != null) {
            for (Field field : c.getDeclaredFields()) {
                if (field.isAnnotationPresent(org.hibernate.search.annotations.Field.class) 
                    || field.isAnnotationPresent(org.hibernate.search.annotations.Fields.class)) {

                    if (field.getType().isAssignableFrom(String.class)) {
                        fields.add(field.getName());
                    }
                }
            }
            c = c.getSuperclass();
        }
        return fields.toArray(new String[fields.size()]);
    }

1 Ответ

1 голос
/ 18 апреля 2019

В Hibernate Search есть API-интерфейс метаданных.

FullTextSession ftSession = ...;
IndexedTypeDescriptor indexedType = ftSession.getSessionFactory().getIndexedTypeDescriptor(clazz);
for (PropertyDescriptor property : indexedType.getIndexedProperties()) {
    for (FieldDescriptor field : property.getIndexedFields()) {
        if (field.getIndex() == Index.YES) {
            // do something
        }
    }
}

См. этот раздел справочной документации для получения дополнительной информации.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...