Как использовать @Facet со встроенными объектами? - PullRequest
0 голосов
/ 25 февраля 2019

Я пытаюсь перейти с HS 4 на 5, но у меня проблемы с поиском.Я понимаю, что @Facet нужно добавить в граненые поля и, например, видеть это .Но граненое поле, которое я хочу использовать, встроено на 2 уровня ниже, и все, что я получаю, это ошибка:

org.hibernate.search.exception.SearchException: HSEARCH000268: Facet request 'ClientId' tries to facet on  field 'scan.clientGroup.id' which either does not exist or is not configured for faceting (via @Facet). Check your configuration.

Я пробовал @Facet во встроенном объекте во многих различных вариантах, но, похоже, ничего не работает -Я хотел бы знать, как это настроить, спасибо.

Ответы [ 2 ]

0 голосов
/ 27 февраля 2019

Решение, которое вы упомянули в ваш ответ , является правильным.

Другое решение будет иметь @IndexedEmbedded от дочернего элемента к родителю, добавив @Facet непосредственно к идентификатору родителя.и используйте parent.parentId в качестве имени поля в своем запросе на фасетирование, как показано в PR, который я только что отправил .

Основное преимущество вашего решения заключается в том, что если Parentсам индексируется (если он имеет собственный индекс), родительский индекс не будет излишне загрязнен ограненным полем (в отличие от моего решения).

Главный недостаток вашего решения заключается в том, что вы по существуобъявите индексированное поле для переходного поля в вашей сущности (переходное в смысле JPA, т.е. не сопоставлено непосредственно со столбцом базы данных).Это означает, что Hibernate Search не может определить, когда изменится это значение, и в результате Hibernate Search отключит некоторые оптимизации и будет переиндексировать сущность Child всякий раз, когда изменяется свойство Child, любое свойство , даже не связанные.Если ваша сущность мала, редко обновляется или имеет ограниченное количество экземпляров, это может не иметь значения.Просто имейте это в виду, если вы заметите много чтений из базы данных, по-видимому, без причины в будущем.

0 голосов
/ 26 февраля 2019

Я нашел решение.Я понятия не имею, если это рекомендуемый способ, возможно, @yrodiere может прокомментировать?

По сути, просто добавьте метод получения к корневому объекту с соответствующей аннотацией @Facet:

@Indexed
@Entity
public class Child {

...

    @ManyToOne
    @IndexedEmbedded(includeEmbeddedObjectId = true)
    Parent parent;

    @Field(analyze = Analyze.NO)
    @Facet(encoding = FacetEncodingType.STRING)
    public Long getParentId() {
        return parent != null ? parent.getId() : null;
    }
}

затемв запросе:

FullTextQuery fullTextQuery = ftem.createFullTextQuery(luceneQuery);

        FacetingRequest facetingRequest = builder.facet()
                .name("facetRequest")
                .onField("parentId")
                .discrete()
                .orderedBy(FacetSortOrder.COUNT_DESC)
                .includeZeroCounts(false)
                .maxFacetCount(10)
                .createFacetingRequest();

        FacetManager facetManager = fullTextQuery.getFacetManager();
        facetManager.enableFaceting(facetingRequest);

        List<Facet> facets = facetManager.getFacets("facetRequest");

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

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