Lucene 休眠搜索

时间:2021-05-05 23:45:15

标签: java lucene hibernate-search

我正在尝试实现 lucene 搜索。我按照以下方式构建了 Repo 公共类 CustomizedContentItemRepositoryImpl 实现 CustomizedContentItemRepository {

@PersistenceContext
private EntityManager entityManager;

@Override
public List<ContentItem> librarySearch(String searchText) {

    SearchResult<ContentItem> result = Search.session(entityManager).search(ContentItem.class)
            .where(f -> f.match()
                    .fields("description", "title", "creator.firstName", "creator.lastName")
                    .matching(searchText))
            .fetchAll();
    List<ContentItem> contentItems = result.hits();
    return contentItems;
}

还有服务 Impl 作为流:

public List<ContentItem> searchContentItems(String searchText) {
    return contentItemRepository.librarySearch(searchText);
}

当我测试它时,我总是得到一个空值

这是一个测试代码 @测试 void searchContentItems() 抛出 InterruptedException { ContentItem video1 = createContentItem(ContentType.VIDEO); contentItemRepository.save(video1);

    ContentItem video2 = createContentItem(ContentType.VIDEO, 1000);
    video2.getSubjects().clear();
    contentItemRepository.save(video2);

    ContentItem audio = createContentItem(ContentType.AUDIO);
    contentItemRepository.save(audio);
    assertEquals(3, contentItemRepository.findAll().size());

        Search.session(entityManager)
                .massIndexer(ContentItem.class)
                .startAndWait();

    Collection<ContentItem> videos = contentItemService.searchContentItems("type");
    assertEquals(2, videos.size());
    Iterator<ContentItem> iterator = videos.iterator();
    assertEquals(video2.getId(), iterator.next().getId());
    assertEquals(video1.getId(), iterator.next().getId());
}

1 个答案:

答案 0 :(得分:1)

您得到的是 null 值,还是只是一个空列表?您很可能会得到一个空列表。

您观察到的结果是由于 indexing happens when you commit a transaction 这一事实。据我所知,您的测试未使用事务,因此您永远不会索引任何内容。

请注意,批量索引也没有用:因为您的 ORM 会话甚至没有刷新到数据库,批量索引器(使用自己的会话)只会看到一个空数据库。

尝试将各种操作封装在事务模板中,如here所述:


@Autowired
TransactionTemplate transactionTemplate;

@Test
void searchContentItems() throws InterruptedException {
    transactionTemplate.execute(ignored -> {
        ContentItem video1 = createContentItem(ContentType.VIDEO);
        contentItemRepository.save(video1);

        ContentItem video2 = createContentItem(ContentType.VIDEO, 1000);
        video2.getSubjects().clear();
        contentItemRepository.save(video2);

        ContentItem audio = createContentItem(ContentType.AUDIO);
        contentItemRepository.save(audio);
        return null;
    });

    transactionTemplate.execute(ignored -> {
        assertEquals(3, contentItemRepository.findAll().size());

        Collection<ContentItem> videos = contentItemService.searchContentItems("type");
        assertEquals(2, videos.size());
        Iterator<ContentItem> iterator = videos.iterator();
        assertEquals(video2.getId(), iterator.next().getId());
        assertEquals(video1.getId(), iterator.next().getId());
        return null;
    });
}

为了通过此测试,您还需要配置 Hibernate Search 以等待索引编制完成,然后再继续进行下一个事务。您可以通过将 automatic indexing synchronization strategy 设置为 sync 来实现。

src/test/resources/application.properties中:

hibernate.search.automatic_indexing.synchronization.strategy = sync