我正在尝试实现 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());
}
答案 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