/** * Searches the lucene store for a specific query * * @param <T> What type of information are we searching * @param clazz The class of the information we are searching * @param queryText The query text * @return list of entities * @throws ParseException the parse exception */ public final <T extends BaseEntity> List<Object[]> search(final Class<T> clazz, final String queryText) throws ParseException { final FullTextEntityManager fullTextEntityManager = Search.getFullTextEntityManager(entityManager); final SearchFactory searchFactory = fullTextEntityManager.getSearchFactory(); final QueryParser parser = new MultiFieldQueryParser(getClassLuceneFields(clazz), searchFactory.getAnalyzer(clazz)); final List<Query> parsedQueries = Arrays.stream(queryText.split("AND")) .map(e -> parseQuery(e, parser)) .filter(Objects::nonNull) .collect(Collectors.toList()); final BooleanQuery.Builder bq = new BooleanQuery.Builder(); parsedQueries.forEach(e -> bq.add(e, BooleanClause.Occur.MUST)); final FullTextQuery jpaQuery = fullTextEntityManager.createFullTextQuery(bq.build(), clazz); jpaQuery.setProjection(ProjectionConstants.SCORE, ProjectionConstants.EXPLANATION, ProjectionConstants.THIS); return (List<Object[]>) jpaQuery.getResultList(); }
@Override @SuppressWarnings("unchecked") public List<PostPO> searchByTag(Paging paigng, String tag) { FullTextSession fullTextSession = Search.getFullTextSession(super.session()); SearchFactory sf = fullTextSession.getSearchFactory(); QueryBuilder qb = sf.buildQueryBuilder().forEntity(PostPO.class).get(); org.apache.lucene.search.Query luceneQuery = qb.phrase().onField("tags").sentence(tag).createQuery(); FullTextQuery query = fullTextSession.createFullTextQuery(luceneQuery); query.setFirstResult(paigng.getFirstResult()); query.setMaxResults(paigng.getMaxResults()); Sort sort = new Sort(new SortField("id", SortField.Type.LONG, true)); query.setSort(sort); paigng.setTotalCount(query.getResultSize()); return query.list(); }
/** * Test provide and dispose. */ @Test public void testProvideDispose() { SessionFactory sessionFactory = locator.getService(SessionFactory.class); Session hibernateSession = sessionFactory.openSession(); FullTextSession ftSession = Search.getFullTextSession(hibernateSession); FulltextSearchFactoryFactory factory = new FulltextSearchFactoryFactory(ftSession); // Make sure that we can create a search factory. SearchFactory searchFactory = factory.provide(); Assert.assertNotNull(searchFactory); // Make sure we can dispose of the factory (does nothing, sadly). factory.dispose(searchFactory); if (hibernateSession.isOpen()) { hibernateSession.close(); } }
@Test public void searchTest() throws Exception { FullTextQuery ftq = createMock(FullTextQuery.class); FullTextSession fts = createMock(FullTextSession.class); SearchFactory factory = createMock(SearchFactory.class); expect(fts.getSearchFactory()).andReturn(factory); expect(factory.getAnalyzer(Item.class)).andReturn(new StandardAnalyzer(Version.LUCENE_36)); expect(fts.createFullTextQuery(isA(Query.class), eq(Item.class))).andReturn(ftq); expect(ftq.setProjection("title")).andReturn(ftq); List<Object[]> results = new ArrayList<Object[]>(); results.add(new Object[] { "The Incredibles" }); expect(ftq.list()).andReturn(results); replay(factory); replay(ftq); replay(fts); }
/** * * @param clazz */ private long reindexMassIndexer(final Class< ? > clazz) { final Session session = getSession(); final Criteria criteria = createCriteria(session, clazz, null, true); final Long number = (Long) criteria.uniqueResult(); // Get number of objects to re-index (select count(*) from). log.info("Starting (mass) re-indexing of " + number + " entries of type " + clazz.getName() + "..."); final FullTextSession fullTextSession = Search.getFullTextSession(session); try { fullTextSession.createIndexer(clazz)// .batchSizeToLoadObjects(25) // //.cacheMode(CacheMode.NORMAL) // .threadsToLoadObjects(5) // //.threadsForIndexWriter(1) // .threadsForSubsequentFetching(20) // .startAndWait(); } catch (final InterruptedException ex) { log.error("Exception encountered while reindexing: " + ex.getMessage(), ex); } final SearchFactory searchFactory = fullTextSession.getSearchFactory(); searchFactory.optimize(clazz); log.info("Re-indexing of " + number + " objects of type " + clazz.getName() + " done."); return number; }
@Override @SuppressWarnings("unchecked") public List<Post> search(Paging paging, String q) throws Exception { FullTextSession fullTextSession = Search.getFullTextSession(super.session()); SearchFactory sf = fullTextSession.getSearchFactory(); QueryBuilder qb = sf.buildQueryBuilder().forEntity(PostPO.class).get(); org.apache.lucene.search.Query luceneQuery = qb.keyword().onFields("title","summary","tags").matching(q).createQuery(); FullTextQuery query = fullTextSession.createFullTextQuery(luceneQuery); query.setFirstResult(paging.getFirstResult()); query.setMaxResults(paging.getMaxResults()); StandardAnalyzer standardAnalyzer = new StandardAnalyzer(); SimpleHTMLFormatter formatter = new SimpleHTMLFormatter("<span style='color:red;'>", "</span>"); QueryScorer queryScorer = new QueryScorer(luceneQuery); Highlighter highlighter = new Highlighter(formatter, queryScorer); List<PostPO> list = query.list(); List<Post> rets = new ArrayList<>(list.size()); for (PostPO po : list) { Post m = BeanMapUtils.copy(po, 0); // 处理高亮 String title = highlighter.getBestFragment(standardAnalyzer, "title", m.getTitle()); String summary = highlighter.getBestFragment(standardAnalyzer, "summary", m.getSummary()); if (StringUtils.isNotEmpty(title)) { m.setTitle(title); } if (StringUtils.isNotEmpty(summary)) { m.setSummary(summary); } rets.add(m); } paging.setTotalCount(query.getResultSize()); return rets; }
/** * Do real indexes optimization. */ public static void optimizeIndexes() throws Exception { FullTextSession ftSession = null; Session session = null; if (optimizeIndexesRunning) { log.warn("*** Optimize indexes already running ***"); } else { optimizeIndexesRunning = true; log.debug("*** Begin optimize indexes ***"); try { session = HibernateUtil.getSessionFactory().openSession(); ftSession = Search.getFullTextSession(session); // Optimize indexes SearchFactory searchFactory = ftSession.getSearchFactory(); searchFactory.optimize(); } catch (Exception e) { throw e; } finally { optimizeIndexesRunning = false; HibernateUtil.close(ftSession); HibernateUtil.close(session); } log.debug("*** End optimize indexes ***"); } }
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); } }
protected void buildSpellCheckerIndex(SearchFactory searchFactory) { IndexReader reader = null; Directory dir = null; long _entr = System.currentTimeMillis(); File spellCheckIndexDir = new File("lucene_index/spellcheck"); log.info("Building SpellChecker index in {0}", spellCheckIndexDir.getAbsolutePath()); ReaderProvider readerProvider = searchFactory.getReaderProvider(); try { reader = readerProvider.openReader(searchFactory.getDirectoryProviders(NodeDocumentVersion.class)[0]); dir = FSDirectory.open(spellCheckIndexDir); SpellChecker spell = new SpellChecker(dir); spell.clearIndex(); spell.indexDictionary(new LuceneDictionary(reader, NodeDocument.TEXT_FIELD)); spell.close(); dir.close(); dir = null; long _exit = System.currentTimeMillis(); log.info("Took {1} (ms) to build SpellChecker index in {0}", spellCheckIndexDir.getAbsolutePath(), String.valueOf((_exit - _entr))); } catch (Exception exc) { log.error("Failed to build spell checker index!", exc); } finally { if (dir != null) { try { dir.close(); } catch (Exception zzz) { } } if (reader != null) { readerProvider.closeReader(reader); } } }
/** * Get Lucene index reader. */ @SuppressWarnings("rawtypes") private IndexReader getReader(FullTextSession session, Class entity) { SearchFactory searchFactory = session.getSearchFactory(); DirectoryProvider provider = searchFactory.getDirectoryProviders(entity)[0]; ReaderProvider readerProvider = searchFactory.getReaderProvider(); return readerProvider.openReader(provider); }
/** * @see MassIndexerImpl#toRootEntities */ protected Set<Class<?>> getIndexedRootEntities(SearchFactory searchFactory, Class<?>... selection) { ExtendedSearchIntegrator searchIntegrator = searchFactory.unwrap(ExtendedSearchIntegrator.class); Set<Class<?>> entities = new HashSet<Class<?>>(); // first build the "entities" set containing all indexed subtypes of "selection". for (Class<?> entityType : selection) { Set<Class<?>> targetedClasses = searchIntegrator.getIndexedTypesPolymorphic(new Class[] { entityType }); if (targetedClasses.isEmpty()) { String msg = entityType.getName() + " is not an indexed entity or a subclass of an indexed entity"; throw new IllegalArgumentException(msg); } entities.addAll(targetedClasses); } Set<Class<?>> cleaned = new HashSet<Class<?>>(); Set<Class<?>> toRemove = new HashSet<Class<?>>(); //now remove all repeated types to avoid duplicate loading by polymorphic query loading for (Class<?> type : entities) { boolean typeIsOk = true; for (Class<?> existing : cleaned) { if (existing.isAssignableFrom(type)) { typeIsOk = false; break; } if (type.isAssignableFrom(existing)) { toRemove.add(existing); } } if (typeIsOk) { cleaned.add(type); } } cleaned.removeAll(toRemove); return cleaned; }
public IndexReader getReader( ) { SearchFactory searchFactory = getFullTextSession( ).getSearchFactory( ); DirectoryProvider<?>[] providers = searchFactory .getDirectoryProviders( entityClass ); return searchFactory.getReaderProvider( ).openReader( providers ); }
/** * Shows the main statistics page */ public void list() { IndexReader indexReader = null; ReaderProvider readerProvider = null; try { SearchFactory searchFactory = Search.createFullTextSession( this.sessionFactory.getCurrentSession()).getSearchFactory(); DirectoryProvider<?> directoryProvider = searchFactory .getDirectoryProviders(Post.class)[0]; readerProvider = searchFactory.getReaderProvider(); indexReader = readerProvider.openReader(directoryProvider); String indexDirectory = directoryProvider.getDirectory().toString(); indexDirectory = indexDirectory.substring(indexDirectory .indexOf('@') + 1); boolean indexExists = IndexReader.indexExists(indexDirectory); this.result.include("indexExists", indexExists); if (indexExists) { this.result.include("numberOfDocs", indexReader.numDocs()); this.result.include("indexLocation", indexDirectory); this.result.include("totalMessages", this.forumRepository.getTotalMessages()); this.result.include("isLocked", IndexReader.isLocked(indexDirectory)); this.result.include("lastModified", new Date(IndexReader.lastModified(indexDirectory))); } } catch (IOException e) { throw new ForumException(e); } finally { if (readerProvider != null && indexReader != null) { readerProvider.closeReader(indexReader); } } }
/** * Create a new instance of our test service. * * @param sr ServiceRegistry * @param f Session Factory * @param s Hibernate Session * @param sF Search Factory * @param ftS Full text session */ @Inject public TestService(final ServiceRegistry sr, final SessionFactory f, final SearchFactory sF, final Session s, final FullTextSession ftS) { serviceRegistry = sr; factory = f; session = s; searchFactory = sF; ftSession = ftS; }
@Override public SearchFactory getSearchFactory() { if ( this.jpaSearchFactoryController != null ) { return this.jpaSearchFactoryController.getSearchFactory(); } return null; }
protected SearchFactoryImplementor getSearchFactoryImpl() { if (log.isDebugEnabled()) log.debug("SearchFactoryImplementor 를 생성합니다."); FullTextSession fts = Search.getFullTextSession(openSession()); fts.close(); SearchFactory searchFactory = fts.getSearchFactory(); return (SearchFactoryImplementor) searchFactory; }
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) { } } } } } } }
/** * Get Lucent document terms. */ @SuppressWarnings("unchecked") public List<String> getTerms(Class<?> entityType, String nodeUuid) throws CorruptIndexException, IOException { List<String> terms = new ArrayList<String>(); FullTextSession ftSession = null; IndexSearcher searcher = null; ReaderProvider provider = null; Session session = null; IndexReader reader = null; try { session = HibernateUtil.getSessionFactory().openSession(); ftSession = Search.getFullTextSession(session); SearchFactory sFactory = ftSession.getSearchFactory(); provider = sFactory.getReaderProvider(); QueryBuilder builder = sFactory.buildQueryBuilder().forEntity(entityType).get(); Query query = builder.keyword().onField("uuid").matching(nodeUuid).createQuery(); DirectoryProvider<Directory>[] dirProv = sFactory.getDirectoryProviders(NodeDocument.class); reader = provider.openReader(dirProv[0]); searcher = new IndexSearcher(reader); TopDocs topDocs = searcher.search(query, 1); for (ScoreDoc sDoc : topDocs.scoreDocs) { if (!reader.isDeleted(sDoc.doc)) { for (TermEnum te = reader.terms(); te.next(); ) { Term t = te.term(); if ("text".equals(t.field())) { for (TermDocs tds = reader.termDocs(t); tds.next(); ) { if (sDoc.doc == tds.doc()) { terms.add(t.text()); //log.info("Field: {} - {}", t.field(), t.text()); } } } } } } } finally { if (provider != null && reader != null) { provider.closeReader(reader); } if (searcher != null) { searcher.close(); } HibernateUtil.close(ftSession); HibernateUtil.close(session); } return terms; }
private void assertDocsInIndex(final Class<?> clazz, final String comment, final int expectedNumDocs, final int expectedNumIndexedAttributes, final List<String> expectedAttributes) throws Exception { Boolean evaluationTookPlace = runTX(new Callable<Boolean>() { @Override public Boolean call() throws Exception { boolean evaluatedIndex = false; Session session = dm.getSession(); if (session != null) { FullTextSession fullTextSession = Search .getFullTextSession(session); SearchFactory searchFactory = fullTextSession .getSearchFactory(); IndexReader reader = searchFactory.getIndexReaderAccessor() .open(clazz); try { assertEquals(comment, expectedNumDocs, reader.numDocs()); if (expectedNumDocs > 0) { final FieldInfos indexedFieldNames = MultiFields .getMergedFieldInfos(reader); for (String expectedAttr : expectedAttributes) { assertNotNull( "attribute " + expectedAttr + " does not exist in index: " + indexedFieldNames, indexedFieldNames .fieldInfo(expectedAttr)); } assertNotNull( "attribute \"key\" does not exist in index: " + indexedFieldNames, indexedFieldNames.fieldInfo("key")); assertNotNull( "attribute \"_hibernate_class\" does not exist in index: " + indexedFieldNames, indexedFieldNames .fieldInfo("_hibernate_class")); assertEquals( "More or less attributes indexed than expected, attributes retrieved from index: " + indexedFieldNames, expectedNumIndexedAttributes + 2, indexedFieldNames.size()); evaluatedIndex = true; } } finally { searchFactory.getIndexReaderAccessor().close(reader); } } return Boolean.valueOf(evaluatedIndex); } }); if (expectedNumDocs > 0) { Assert.assertTrue("Index not found, no evaluation took place", evaluationTookPlace.booleanValue()); } }
/** * Generates a lucene query to search for a given term in all the indexed fields of a class * * @param searchTerm the term to search for * @param searchedEntity the class searched * @param sess the hibernate session * @param defaultAnalyzer the default analyzer for parsing the search terms * @return * @throws ParseException */ public static Query generateQuery(String searchTerm, Class searchedEntity, Session sess, Analyzer defaultAnalyzer) throws ParseException { Query qry = null; if (searchTerm.equals("*")) { qry = new MatchAllDocsQuery(); } else { // Search in all indexed fields IndexReaderAccessor readerAccessor = null; IndexReader reader = null; try { FullTextSession txtSession = Search.getFullTextSession(sess); // obtain analyzer to parse the query: Analyzer analyzer; if (searchedEntity == null) { analyzer = defaultAnalyzer; } else { analyzer = txtSession.getSearchFactory().getAnalyzer(searchedEntity); } // search on all indexed fields: generate field list, removing internal hibernate search field name: _hibernate_class // TODO: possible improvement: cache the fields of each entity SearchFactory searchFactory = txtSession.getSearchFactory(); readerAccessor = searchFactory.getIndexReaderAccessor(); reader = readerAccessor.open(searchedEntity); Collection<String> fieldNames = reader.getFieldNames(IndexReader.FieldOption.INDEXED); fieldNames.remove("_hibernate_class"); String[] fnames = new String[0]; fnames = fieldNames.toArray(fnames); // To search on all fields, search the term in all fields String[] queries = new String[fnames.length]; for (int i = 0; i < queries.length; ++i) { queries[i] = searchTerm; } qry = MultiFieldQueryParser.parse(Version.LUCENE_35, queries, fnames, analyzer); } finally { if (readerAccessor != null && reader != null) { readerAccessor.close(reader); } } } return qry; }
protected static SearchFactory getSearchFactory() { return getFullTextSession().getSearchFactory(); }
private SearchFactory getSearchFactory() { return getFullTextEntityManager().getSearchFactory(); }
/** * Create a request-scoped SearchFactory. * * @return A new SearchFactory */ @Override public SearchFactory provide() { logger.trace("Creating hibernate search factory."); return session.getSearchFactory(); }
@Override protected void configure() { bindFactory(FulltextSearchFactoryFactory.class) .to(SearchFactory.class) .in(RequestScoped.class); }
@Override public SearchFactory getSearchFactory() { return this.searchFactory; }
/** * Create search factory bean * * @return the search factory */ @Bean public SearchFactory searchFactory() { return fullTextEntityManager().getSearchFactory(); }
/** * Dispose of the search factory. * * @param factory The factory to dispose of. */ @Override public void dispose(final SearchFactory factory) { // Do nothing- the factory has no disposal requirements. }
/** * @return the <code>SearchFactory</code> instance. */ SearchFactory getSearchFactory();
/** * @return the underlying SearchFactory */ SearchFactory getSearchFactory();