下面列出了怎么用org.hibernate.search.jpa.FullTextEntityManager的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
void performMultiResultLuceneIndexSearch() {
FullTextEntityManager fullTextSession = Search.getFullTextEntityManager(entityManager);
QueryBuilder builder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(Dog.class).get();
BooleanJunction<BooleanJunction> bool = builder.bool();
bool.should(builder.keyword().wildcard().onField("name").matching("dog*").createQuery());
Query query = bool.createQuery();
FullTextQuery ftq = fullTextSession.createFullTextQuery(query, Dog.class);
List<Dog> result = (List<Dog>) ftq.getResultList();
assertAll(() -> {
assertThat(result.size()).isEqualTo(2);
assertApmSpanInformation(reporter, "name:dog*", "list");
});
}
@Test
public void searchSubscriptions() throws Exception {
DataServiceBean bean = spy(new DataServiceBean());
SubscriptionSearchServiceBean ssb = spy(
new SubscriptionSearchServiceBean());
doReturn(bean).when(ssb).getDm();
FullTextEntityManager ftem = mock(FullTextEntityManager.class,
Mockito.RETURNS_DEEP_STUBS);
doReturn(ftem).when(ssb).getFtem();
Subscription sub = new Subscription();
sub.setKey(1L);
FullTextQuery fullTextQuery = mock(FullTextQuery.class);
when(ftem.createFullTextQuery(any(BooleanQuery.class),
any(Class.class))).thenReturn(fullTextQuery);
doReturn(Arrays.asList(sub)).when(fullTextQuery).getResultList();
Collection<Long> result = ssb.searchSubscriptions("searchphrase");
assertTrue(result.contains(new Long(1L)));
}
@SuppressWarnings("unchecked")
public <T> List<T> find(Class<T> clazz, SearchParameters sp, List<SingularAttribute<?, ?>> availableProperties) {
// log.info("Searching {} with terms : {} with available Properties: {}", new Object[]{clazz.getSimpleName(), sp.getTerms(), availableProperties});
FullTextEntityManager fullTextEntityManager = getFullTextEntityManager(entityManager);
Query query = sp.getLuceneQueryBuilder().build(fullTextEntityManager, sp, availableProperties);
if (query == null) {
return null;
}
FullTextQuery ftq = fullTextEntityManager.createFullTextQuery( //
query, clazz);
if (sp.getMaxResults() > 0) {
ftq.setMaxResults(sp.getMaxResults());
}
return ftq.getResultList();
}
@SuppressWarnings("unchecked")
public <T> List<Serializable> findId(Class<T> clazz, SearchParameters sp, List<SingularAttribute<?, ?>> availableProperties) {
//log.info("Searching {} with terms : {} with available Properties: {}", new Object[]{clazz.getSimpleName(), sp.getTerms(), availableProperties});
FullTextEntityManager fullTextEntityManager = getFullTextEntityManager(entityManager);
Query query = sp.getLuceneQueryBuilder().build(fullTextEntityManager, sp, availableProperties);
if (query == null) {
return null;
}
FullTextQuery ftq = fullTextEntityManager.createFullTextQuery( //
query, clazz);
ftq.setProjection("id");
if (sp.getMaxResults() > 0) {
ftq.setMaxResults(sp.getMaxResults());
}
List<Serializable> ids = newArrayList();
List<Object[]> resultList = ftq.getResultList();
for (Object[] result : resultList) {
ids.add((Serializable) result[0]);
}
return ids;
}
@Override
public Query build(FullTextEntityManager fullTextEntityManager, SearchParameters searchParameters, List<SingularAttribute<?, ?>> availableProperties) {
List<String> clauses = getAllClauses(searchParameters, searchParameters.getTerms(), availableProperties);
StringBuilder query = new StringBuilder();
query.append("+(");
for (String clause : clauses) {
if (query.length() > 2) {
query.append(" AND ");
}
query.append(clause);
}
query.append(")");
if (query.length() == 3) {
return null;
}
//log.debug("Lucene query: {}", query);
try {
return new QueryParser(availableProperties.get(0).getName(), fullTextEntityManager.getSearchFactory().getAnalyzer("custom"))
.parse(query.toString());
} catch (Exception e) {
throw propagate(e);
}
}
@Override
public List<Owner> search(String searchterm) {
FullTextEntityManager fullTextEntityManager =
org.hibernate.search.jpa.Search.getFullTextEntityManager(entityManager);
QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder().forEntity( Owner.class ).get();
org.apache.lucene.search.Query query = qb
.keyword()
.onFields("firstName", "lastName", "city", "pets.name")
.matching(searchterm)
.createQuery();
// wrap Lucene query in a javax.persistence.Query
javax.persistence.Query persistenceQuery =
fullTextEntityManager.createFullTextQuery(query, Owner.class);
// execute search
@SuppressWarnings("unchecked")
List<Owner> result = persistenceQuery.getResultList();
return result;
}
@Override
public List<Vet> search(String searchterm){
FullTextEntityManager fullTextEntityManager =
org.hibernate.search.jpa.Search.getFullTextEntityManager(entityManager);
QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder().forEntity( Vet.class ).get();
org.apache.lucene.search.Query query = qb
.keyword()
.onFields("firstName", "lastName")
.matching(searchterm)
.createQuery();
// wrap Lucene query in a javax.persistence.Query
javax.persistence.Query persistenceQuery =
fullTextEntityManager.createFullTextQuery(query, Vet.class);
// execute search
@SuppressWarnings("unchecked")
List<Vet> result = persistenceQuery.getResultList();
return result;
}
@Test
public void queryOnSingleField() {
EntityManager em = emf.createEntityManager();
inTransaction( em, tx -> {
FullTextEntityManager ftem = Search.getFullTextEntityManager( em );
QueryBuilder qb = ftem.getSearchFactory()
.buildQueryBuilder()
.forEntity( VideoGame.class )
.get();
FullTextQuery query = ftem.createFullTextQuery(
qb.keyword().onField( "title" ).matching( "samurai" ).createQuery(),
VideoGame.class
);
List<VideoGame> videoGames = query.getResultList();
assertThat( videoGames ).onProperty( "title" ).containsExactly( "Revenge of the Samurai" );
} );
em.close();
}
@Test
public void queryOnMultipleFields() {
EntityManager em = emf.createEntityManager();
inTransaction( em, tx -> {
FullTextEntityManager ftem = Search.getFullTextEntityManager( em );
QueryBuilder qb = ftem.getSearchFactory()
.buildQueryBuilder()
.forEntity( VideoGame.class )
.get();
FullTextQuery query = ftem.createFullTextQuery(
qb.keyword().onFields( "title", "description").matching( "samurai" ).createQuery(),
VideoGame.class
);
List<VideoGame> videoGames = query.getResultList();
assertThat( videoGames ).onProperty( "title" ).containsExactly( "Revenge of the Samurai", "Tanaka's return" );
} );
em.close();
}
@Test
public void wildcardQuery() {
EntityManager em = emf.createEntityManager();
inTransaction( em, tx -> {
FullTextEntityManager ftem = Search.getFullTextEntityManager( em );
QueryBuilder qb = ftem.getSearchFactory()
.buildQueryBuilder()
.forEntity( VideoGame.class )
.get();
FullTextQuery query = ftem.createFullTextQuery(
qb.keyword().wildcard().onFields( "title", "description").matching( "sam*" ).createQuery(),
VideoGame.class
);
List<VideoGame> videoGames = query.getResultList();
assertThat( videoGames ).onProperty( "title" ).containsExactly( "Revenge of the Samurai", "Tanaka's return" );
} );
em.close();
}
@Test
public void rangeQuery() {
EntityManager em = emf.createEntityManager();
inTransaction( em, tx -> {
FullTextEntityManager ftem = Search.getFullTextEntityManager( em );
QueryBuilder qb = ftem.getSearchFactory()
.buildQueryBuilder()
.forEntity( VideoGame.class )
.get();
FullTextQuery query = ftem.createFullTextQuery(
qb.range()
.onField( "rating" )
.from( 2 )
.to( 9 )
.createQuery(),
VideoGame.class
);
List<VideoGame> videoGames = query.getResultList();
assertThat( videoGames ).onProperty( "title" ).containsOnly( "Revenge of the Samurai", "Ninja Castle" );
} );
em.close();
}
@Test
public void queryString() {
EntityManager em = emf.createEntityManager();
inTransaction( em, tx -> {
FullTextEntityManager ftem = Search.getFullTextEntityManager( em );
QueryBuilder qb = ftem.getSearchFactory()
.buildQueryBuilder()
.forEntity( VideoGame.class )
.get();
FullTextQuery query = ftem.createFullTextQuery(
ElasticsearchQueries.fromQueryString( "title:sam* OR description:sam*" ),
VideoGame.class
);
List<VideoGame> videoGames = query.getResultList();
assertThat( videoGames ).onProperty( "title" ).containsExactly( "Revenge of the Samurai", "Tanaka's return" );
} );
em.close();
}
private FullTextQuery getSearchByNameQuery(String searchTerm) {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(getEntityManager());
QueryBuilder projectQueryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder()
.forEntity(Project.class).get();
BooleanJunction<?> booleanJunction = projectQueryBuilder.bool();
if (StringUtils.hasText(searchTerm)) {
booleanJunction.must(projectQueryBuilder
.keyword()
.fuzzy().withPrefixLength(1).withThreshold(0.8F)
.onField(Binding.project().name().getPath())
.matching(searchTerm)
.createQuery());
} else {
booleanJunction.must(projectQueryBuilder.all().createQuery());
}
return fullTextEntityManager.createFullTextQuery(booleanJunction.createQuery(), Project.class);
}
private FullTextQuery getSearchQuery(String searchTerm) {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(getEntityManager());
QueryBuilder userQueryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder()
.forEntity(User.class).get();
BooleanJunction<?> booleanJunction = userQueryBuilder.bool();
if (StringUtils.hasText(searchTerm)) {
booleanJunction.must(userQueryBuilder
.keyword()
.fuzzy().withPrefixLength(1).withThreshold(0.8F)
.onField(Binding.user().userName().getPath())
.andField(Binding.user().fullName().getPath())
.matching(searchTerm)
.createQuery());
} else {
booleanJunction.must(userQueryBuilder.all().createQuery());
}
return fullTextEntityManager.createFullTextQuery(booleanJunction.createQuery(), User.class);
}
@Test
void performLuceneIndexSearch() {
FullTextEntityManager fullTextSession = Search.getFullTextEntityManager(entityManager);
FullTextQuery ftq = fullTextSession.createFullTextQuery(createQueryForDog1(), Dog.class);
List<Dog> result = (List<Dog>) ftq.getResultList();
assertAll(() -> {
assertThat(result.size()).isEqualTo(1);
assertThat(result.get(0).getName()).isEqualTo("dog1");
assertApmSpanInformation(reporter, "name:dog1", "list");
});
}
public List<MagicCard> findByName(String name) {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager( em );
QueryBuilder queryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder().forEntity( MagicCard.class ).get();
Query query = queryBuilder.keyword().onField( "name" ).matching( name ).createQuery();
return fullTextEntityManager.createFullTextQuery( query, MagicCard.class ).getResultList();
}
public static Member findWithEmail(EntityManager em, String email) {
FullTextEntityManager ftem = Search.getFullTextEntityManager( em );
QueryBuilder b = ftem.getSearchFactory().buildQueryBuilder().forEntity( Member.class ).get();
Query lq = b.keyword().wildcard().onField( "email" ).matching( email ).createQuery();
Object uniqueResult = ftem.createFullTextQuery( lq ).getSingleResult();
return (Member) uniqueResult;
}
public void checkIndexOnStartup() {
//log.info("Observed event {1} from Thread {0}", Thread.currentThread().getName(), App.INIT_SUCCESS);
// See if we need to rebuild the index during startup ...
FullTextEntityManager ftEm = Search.getFullTextEntityManager(entityManager);
SearchFactory searchFactory = ftEm.getSearchFactory();
ReaderProvider readerProvider = searchFactory.getReaderProvider();
IndexReader reader = readerProvider.openReader(searchFactory.getDirectoryProviders(NodeDocumentVersion.class)[0]);
int maxDoc = 0;
try {
maxDoc = reader.maxDoc();
} finally {
readerProvider.closeReader(reader);
}
if (maxDoc == 0) {
log.warn("No objects indexed ... rebuilding Lucene search index from database ...");
long _exit = 0L;
long _entr = System.currentTimeMillis();
try {
int docs = doRebuildIndex();
_exit = System.currentTimeMillis();
log.info("Took " + (_exit - _entr)
+ " (ms) to re-build the index containing " + docs
+ " documents.");
} catch (Exception exc) {
if (exc instanceof RuntimeException) {
throw (RuntimeException) exc;
} else {
throw new RuntimeException(exc);
}
}
// build the spell checker index off of the HS index.
buildSpellCheckerIndex(searchFactory);
}
}
@Override
public List<?> searchEntriesForUserHelper(String userId, String field,
String query, int startPosition, int maxResults) {
if (userId == null || userId.isEmpty()
|| !idGenerator.isIdWellFormed(userId)) {
return new ArrayList<Entry>();
}
if (query == null) {
return new ArrayList<Entry>();
}
if (field == null) {
return new ArrayList<Entry>();
}
FullTextEntityManager fullTextEntityManager = org.hibernate.search.jpa.Search
.getFullTextEntityManager(getOrCreateEntityManager());
QueryBuilder qb = fullTextEntityManager.getSearchFactory()
.buildQueryBuilder().forEntity(Entry.class).get();
org.apache.lucene.search.Query luceneQuery = qb
.bool()
.must(qb.keyword().onField(field).matching(query).createQuery())
.must(new TermQuery(new Term("userId", userId))).createQuery();
javax.persistence.Query jpaQuery = fullTextEntityManager
.createFullTextQuery(luceneQuery, Entry.class)
.setFirstResult(startPosition).setMaxResults(maxResults);
return jpaQuery.getResultList();
}
@Override
public void afterPropertiesSet() throws Exception {
//重建索引
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(em);
fullTextEntityManager.createIndexer().startAndWait();
}
@Test
public void projectionWithTransformer() {
EntityManager em = emf.createEntityManager();
inTransaction( em, tx -> {
FullTextEntityManager ftem = Search.getFullTextEntityManager( em );
QueryBuilder qb = ftem.getSearchFactory()
.buildQueryBuilder()
.forEntity( VideoGame.class )
.get();
FullTextQuery query = ftem.createFullTextQuery(
qb.keyword()
.onField( "tags" )
.matching( "round-based" )
.createQuery(),
VideoGame.class
)
.setProjection( "title", "publisher.name", "release" )
.setResultTransformer( new BasicTransformerAdapter() {
@Override
public VideoGameDto transformTuple(Object[] tuple, String[] aliases) {
return new VideoGameDto( (String) tuple[0], (String) tuple[1], (Date) tuple[2] );
}
} );
VideoGameDto projection = (VideoGameDto) query.getSingleResult();
assertThat( projection.getTitle() ).isEqualTo( "Tanaka's return" );
assertThat( projection.getPublisherName() ).isEqualTo( "Samurai Games, Inc." );
assertThat( projection.getRelease() ).isEqualTo( new GregorianCalendar( 2011, 2, 13 ).getTime() );
} );
em.close();
}
@Test
@Ignore
public void manualIndexing() {
EntityManager em = emf.createEntityManager();
FullTextEntityManager ftem = Search.getFullTextEntityManager( em );
ftem.getTransaction().begin();
VideoGame game = ftem.find( VideoGame.class, 311 );
ftem.index( game );
ftem.getTransaction().commit();
}
@Test
public void canSearchUsingFullTextQuery() {
EntityManager entityManager = entityManagerFactory.createEntityManager();
entityManager.getTransaction().begin();
//Add full-text superpowers to any EntityManager:
FullTextEntityManager ftem = Search.getFullTextEntityManager(entityManager);
// Optionally use the QueryBuilder to simplify Query definition:
QueryBuilder b = ftem.getSearchFactory().buildQueryBuilder().forEntity( Hike.class ).get();
// A lucene query to look for hike to the Carisbrooke castle:
// Note that the query looks for "cariboke" instead of "Carisbrooke"
Query lq = b.keyword().onField("description").matching("carisbroke castle").createQuery();
//Transform the Lucene Query in a JPA Query:
FullTextQuery ftQuery = ftem.createFullTextQuery(lq, Hike.class);
//This is a requirement when using Hibernate OGM instead of ORM:
ftQuery.initializeObjectsWith( ObjectLookupMethod.SKIP, DatabaseRetrievalMethod.FIND_BY_ID );
// List matching hikes
List<Hike> hikes = ftQuery.getResultList();
assertThat( hikes ).onProperty( "description" ).containsOnly( "Exploring Carisbrooke Castle" );
entityManager.getTransaction().commit();
entityManager.close();
}
private QueryBuilder getQueryBuilder() {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
return fullTextEntityManager.getSearchFactory()
.buildQueryBuilder()
.forEntity(Product.class)
.get();
}
@Test
public void testB_whenIndexInitialized_thenCorrectIndexSize() throws InterruptedException {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
fullTextEntityManager.createIndexer()
.startAndWait();
int indexSize = fullTextEntityManager.getSearchFactory()
.getStatistics()
.getNumberOfIndexedEntities(Product.class.getName());
assertEquals(products.size() - 1, indexSize);
}
@Test
public void testD_whenAdditionalTestDataInserted_thenIndexUpdatedAutomatically() {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager);
int indexSize = fullTextEntityManager.getSearchFactory()
.getStatistics()
.getNumberOfIndexedEntities(Product.class.getName());
assertEquals(products.size(), indexSize);
}
private FullTextQuery getSearchByNameQuery(String searchTerm, ArtifactDeprecationStatus deprecation) {
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(getEntityManager());
QueryBuilder artifactQueryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder()
.forEntity(Artifact.class).get();
BooleanJunction<?> booleanJunction = artifactQueryBuilder.bool();
if (deprecation != null) {
booleanJunction.must(artifactQueryBuilder
.keyword()
.onField(Binding.artifact().deprecationStatus().getPath())
.matching(deprecation)
.createQuery());
}
if (StringUtils.hasText(searchTerm)) {
booleanJunction.must(artifactQueryBuilder
.keyword()
.fuzzy().withPrefixLength(1).withThreshold(0.8F)
.onField(Binding.artifact().artifactId().getPath())
.andField(Binding.artifact().group().groupId().getPath())
.matching(searchTerm)
.createQuery());
} else {
booleanJunction.must(artifactQueryBuilder.all().createQuery());
}
return fullTextEntityManager.createFullTextQuery(booleanJunction.createQuery(), Artifact.class);
}
private FullTextQuery getSearchRecommendedQuery(String searchTerm) throws ServiceException {
if (!StringUtils.hasText(searchTerm)) {
return null;
}
FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(getEntityManager());
QueryBuilder artifactQueryBuilder = fullTextEntityManager.getSearchFactory().buildQueryBuilder()
.forEntity(Artifact.class).get();
BooleanJunction<?> booleanJunction = artifactQueryBuilder.bool();
booleanJunction.must(artifactQueryBuilder
.keyword()
.onField(Binding.artifact().deprecationStatus().getPath())
.matching(ArtifactDeprecationStatus.NORMAL)
.createQuery());
try {
searchTerm = LuceneUtils.getSimilarityQuery(searchTerm, 2);
String[] fields = new String[] {
Binding.artifact().artifactId().getPath(),
Binding.artifact().group().groupId().getPath()
};
Analyzer analyzer = Search.getFullTextEntityManager(getEntityManager()).getSearchFactory().getAnalyzer(Artifact.class);
MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, analyzer);
parser.setDefaultOperator(MultiFieldQueryParser.AND_OPERATOR);
BooleanQuery booleanQuery = new BooleanQuery();
booleanQuery.add(parser.parse(searchTerm), BooleanClause.Occur.MUST);
booleanJunction.must(booleanQuery);
} catch (ParseException e) {
throw new ServiceException(String.format("Error parsing request: %1$s", searchTerm), e);
}
return fullTextEntityManager.createFullTextQuery(booleanJunction.createQuery(), Artifact.class);
}
public void updateSpellCheckerIndex(NodeDocumentVersion nDocVer) {
log.info("Observed Wine added/updated event for {1} from Thread {0}",
Thread.currentThread().getName(), String.valueOf(nDocVer));
String text = (nDocVer != null) ? nDocVer.getText() : null;
if (text != null) {
Dictionary dictionary = null;
try {
FullTextEntityManager ftEm = (FullTextEntityManager) entityManager;
SearchFactory searchFactory = ftEm.getSearchFactory();
dictionary = new SetDictionary(text, searchFactory.getAnalyzer("wine_en"));
} catch (IOException ioExc) {
log.error("Failed to analyze dictionary text {0} from Wine {1} to update spell checker due to: {2}" +
text + nDocVer.getUuid() + ioExc.toString());
}
if (dictionary != null) {
Directory dir = null;
// only allow one thread to update the index at a time ...
// the Dictionary is pre-computed, so it should happen quickly
// ...
// this synchronized approach only works because this component
// is application-scoped
synchronized (this) {
try {
dir = FSDirectory.open(new File("lucene_index/spellcheck"));
SpellChecker spell = new SpellChecker(dir);
spell.indexDictionary(dictionary);
spell.close();
log.info("Successfully updated the spell checker index after Document added/updated.");
} catch (Exception exc) {
log.error("Failed to update the spell checker index!", exc);
} finally {
if (dir != null) {
try {
dir.close();
} catch (Exception zzz) {
}
}
}
}
}
}
}
@SuppressWarnings("unchecked")
@Override
public Collection<Long> searchSubscriptions(String searchPhrase)
throws InvalidPhraseException, ObjectNotFoundException {
ArgumentValidator.notEmptyString("searchPhrase", searchPhrase);
FullTextEntityManager ftem = getFtem();
List<Subscription> list;
BooleanQuery booleanQuery = constructWildcardQuery(searchPhrase);
javax.persistence.Query jpaQuery = ftem.createFullTextQuery(
booleanQuery, Subscription.class);
list = jpaQuery.getResultList();
List<Long> result = new ArrayList<>();
for (Subscription sub : list) {
result.add(new Long(sub.getKey()));
}
return result;
}