Hiberate поиск дочерних объектов - PullRequest
0 голосов
/ 02 июля 2018

У меня есть три класса, определенные как:

1) Класс категории: -

@Entity
@Table(name = "CATEGORY")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Indexed
public class Category {

@Id
@GeneratedValue
private Long id;

@Field(index = Index.YES, store = Store.YES, analyzer = @Analyzer(definition = "ngram"))
private String categoryName;

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "categoryId", referencedColumnName = "id")
@LazyCollection(LazyCollectionOption.TRUE)
@IndexedEmbedded
private List<SubCategory> subCategories;

private Long creationTime;

private Long updationTime;
}

2) Класс подкатегории: -

 @Entity
 @Table(name = "SUB_CATEGORY")
 @Data
 @NoArgsConstructor
 @AllArgsConstructor
 @Indexed
 public class SubCategory {


@Id
@GeneratedValue
private Long id;

@Field(index = Index.YES,store = Store.YES,analyzer = @Analyzer(definition = "ngram1"))
private String subCategoryName;

@Field(index = Index.YES,store = Store.YES)
private Long categoryId;

@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "subCategoryId", referencedColumnName = "id")
@LazyCollection(LazyCollectionOption.TRUE)
@IndexedEmbedded
private List<Pages> pages;

private Long creationTime;
}

3) Класс страниц: -

 @Entity
 @Table(name = "PAGES")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Indexed
public class Pages {

@Id
@GeneratedValue
private Long id;

@Field(index = Index.YES,store = Store.YES,analyzer = @Analyzer(definition = "ngram2"))
private String pageName;

@Field(index = Index.YES,store = Store.YES,analyzer = @Analyzer(definition = "ngram2"))
private String pageDescription;

@Field(index = Index.YES,store = Store.YES,analyzer = @Analyzer(definition = "ngram2"))
private Long subCategoryId;

private Long creationTime;
}

Теперь данные определены так: -

   Category              SubCategory              Pages
   --------              ------------             -------
   Vehicle                Car                     BMW
   Electricals            MotorCycle              Hero
   ...........            ........                Audi
   ...........            ........                ...... 
   Lapzz                  Laptop                  ......
                                                  Dell

Теперь я застрял в получении запроса, который будет искать во всех трех классах с использованием поиска в спящем режиме (т. Е. Если я ищу круг *), я должен получить результат по категориям, подкатегориям и страницам, и только строки, соответствующие запросу, только не завершенный объект категории.

Например, я должен получить в результирующем наборе строку, содержащую Lapzz в категориях, и строку, содержащую Ноутбук в подкатегориях, когда я ищу Lap *. Пожалуйста, помогите мне найти это решение.

1 Ответ

0 голосов
/ 04 июля 2018

Это должно делать то, что вы хотите, насколько я понимаю:

String searchTerms = ...;

QueryBuilder categoryQb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity( Category.class ).get();
QueryBuilder subCategoryQb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity( SubCategory.class ).get();
QueryBuilder pagesQb = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity( Pages.class ).get();

Query categoryQuery = categoryQb.keyword()
    .onField( "categoryName" )
    .matching( searchTerms )
    .createQuery();
Query subCategoryQuery = subCategoryQb.keyword()
    .onField( "subCategoryName" )
    .matching( searchTerms )
    .createQuery();
Query pagesQuery = pagesQb.keyword()
    .onFields(
        "pageName",
        "pageDescription"
    )
    .matching( searchTerms )
    .createQuery();

Query luceneQuery = categoryQb.bool()
        .should( categoryQuery )
        .should( subCategoryQuery )
        .should( pagesQuery )
        .createQuery();

FullTextQuery fullTextQuery = fullTextEntityManager.createFullTextQuery(
    luceneQuery,
    Category.class, SubCategory.class, Pages.class
);

List<?> results = fullTextQuery.getResultList();

Здесь необходимо несколько предупреждений:

  • поскольку вы используете фильтры ngram, вам может потребоваться использовать другой анализатор при запросах; см этот ответ
  • ваша @Field аннотация на Pages.subcategoryId крайне подозрительна: анализировать числовое значение не имеет смысла. В связи с этим, подозрительно хранить идентификатор другой сущности в Pages, вы, как правило, хотите иметь поле с типом SubCategory вместо этого и аннотировать его с помощью @ManyToOne.
  • если вы хотите, чтобы ваш запрос соответствовал категории, в которой нет поисковых терминов в описании, но содержит страницу, имя или описание которой содержит поисковые запросы, вам нужно будет добавить IndexedEmbedded и добавьте встроенные поля ("pages.pageName", "pages.pageDescription", ...) к своим поисковым запросам.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...