| | |
| | | *
|
| | | * @param repositoryName
|
| | | */
|
| | | public void close(String repositoryName) {
|
| | | public synchronized void close(String repositoryName) {
|
| | | try {
|
| | | IndexSearcher searcher = searchers.remove(repositoryName);
|
| | | if (searcher != null) {
|
| | | searcher.getIndexReader().close();
|
| | | }
|
| | | } catch (Exception e) {
|
| | | logger.error("Failed to close index searcher for " + repositoryName, e);
|
| | | }
|
| | | |
| | | try {
|
| | | IndexWriter writer = writers.remove(repositoryName);
|
| | | if (writer != null) {
|
| | |
| | | }
|
| | | } catch (Exception e) {
|
| | | logger.error("Failed to close index writer for " + repositoryName, e);
|
| | | }
|
| | |
|
| | | try {
|
| | | IndexSearcher searcher = searchers.remove(repositoryName);
|
| | | if (searcher != null) {
|
| | | searcher.close();
|
| | | }
|
| | | } catch (Exception e) {
|
| | | logger.error("Failed to close index searcher for " + repositoryName, e);
|
| | | }
|
| | | } |
| | | }
|
| | |
|
| | | /**
|
| | | * Close all Lucene indexers.
|
| | | *
|
| | | */
|
| | | public void close() {
|
| | | public synchronized void close() {
|
| | | // close all writers
|
| | | for (String writer : writers.keySet()) {
|
| | | try {
|
| | |
| | | // close all searchers
|
| | | for (String searcher : searchers.keySet()) {
|
| | | try {
|
| | | searchers.get(searcher).close();
|
| | | searchers.get(searcher).getIndexReader().close();
|
| | | } catch (Throwable t) {
|
| | | logger.error("Failed to close Lucene searcher for " + searcher, t);
|
| | | }
|
| | |
| | | */
|
| | | public boolean deleteIndex(String repositoryName) {
|
| | | try {
|
| | | // remove the repository index writer from the cache and close it
|
| | | IndexWriter writer = writers.remove(repositoryName);
|
| | | if (writer != null) {
|
| | | writer.close();
|
| | | writer = null;
|
| | | }
|
| | | // remove the repository index searcher from the cache and close it
|
| | | IndexSearcher searcher = searchers.remove(repositoryName);
|
| | | if (searcher != null) {
|
| | | searcher.close();
|
| | | searcher = null;
|
| | | }
|
| | | // close any open writer/searcher
|
| | | close(repositoryName);
|
| | |
|
| | | // delete the index folder
|
| | | File repositoryFolder = new File(repositoriesFolder, repositoryName);
|
| | | File luceneIndex = new File(repositoryFolder, LUCENE_DIR);
|
| | |
| | | * @return IndexResult
|
| | | */
|
| | | public IndexResult reindex(RepositoryModel model, Repository repository) {
|
| | | IndexResult result = new IndexResult();
|
| | | IndexResult result = new IndexResult(); |
| | | if (!deleteIndex(model.name)) {
|
| | | return result;
|
| | | }
|
| | |
| | | // commit all changes and reset the searcher
|
| | | config.setInt(CONF_INDEX, null, CONF_VERSION, INDEX_VERSION);
|
| | | config.save();
|
| | | resetIndexSearcher(model.name);
|
| | | writer.commit();
|
| | | resetIndexSearcher(model.name);
|
| | | result.success();
|
| | | } catch (Exception e) {
|
| | | logger.error("Exception while reindexing " + model.name, e);
|
| | |
| | | try {
|
| | | IndexWriter writer = getIndexWriter(repositoryName);
|
| | | writer.addDocument(doc);
|
| | | resetIndexSearcher(repositoryName);
|
| | | writer.commit();
|
| | | resetIndexSearcher(repositoryName);
|
| | | return true;
|
| | | } catch (Exception e) {
|
| | | logger.error(MessageFormat.format("Exception while incrementally updating {0} Lucene index", repositoryName), e);
|
| | |
| | | return false;
|
| | | }
|
| | |
|
| | | private SearchResult createSearchResult(Document doc, float score) throws ParseException {
|
| | | private SearchResult createSearchResult(Document doc, float score, int hitId, int totalHits) throws ParseException {
|
| | | SearchResult result = new SearchResult();
|
| | | result.hitId = hitId;
|
| | | result.totalHits = totalHits;
|
| | | result.score = score;
|
| | | result.date = DateTools.stringToDate(doc.get(FIELD_DATE));
|
| | | result.summary = doc.get(FIELD_SUMMARY);
|
| | |
| | | private synchronized void resetIndexSearcher(String repository) throws IOException {
|
| | | IndexSearcher searcher = searchers.remove(repository);
|
| | | if (searcher != null) {
|
| | | searcher.close();
|
| | | searcher.getIndexReader().close();
|
| | | }
|
| | | }
|
| | |
|
| | |
| | | *
|
| | | * @param text
|
| | | * if the text is null or empty, null is returned
|
| | | * @param maximumHits
|
| | | * the maximum number of hits to collect
|
| | | * @param page
|
| | | * the page number to retrieve. page is 1-indexed.
|
| | | * @param pageSize
|
| | | * the number of elements to return for this page
|
| | | * @param repositories
|
| | | * a list of repositories to search. if no repositories are
|
| | | * specified null is returned.
|
| | | * @return a list of SearchResults in order from highest to the lowest score
|
| | | *
|
| | | */
|
| | | public List<SearchResult> search(String text, int maximumHits, List<String> repositories) {
|
| | | public List<SearchResult> search(String text, int page, int pageSize, List<String> repositories) {
|
| | | if (ArrayUtils.isEmpty(repositories)) {
|
| | | return null;
|
| | | }
|
| | | return search(text, maximumHits, repositories.toArray(new String[0]));
|
| | | return search(text, page, pageSize, repositories.toArray(new String[0]));
|
| | | }
|
| | |
|
| | | /**
|
| | |
| | | *
|
| | | * @param text
|
| | | * if the text is null or empty, null is returned
|
| | | * @param maximumHits
|
| | | * the maximum number of hits to collect
|
| | | * @param page
|
| | | * the page number to retrieve. page is 1-indexed.
|
| | | * @param pageSize
|
| | | * the number of elements to return for this page
|
| | | * @param repositories
|
| | | * a list of repositories to search. if no repositories are
|
| | | * specified null is returned.
|
| | | * @return a list of SearchResults in order from highest to the lowest score
|
| | | *
|
| | | */ |
| | | public List<SearchResult> search(String text, int maximumHits, String... repositories) {
|
| | | */
|
| | | public List<SearchResult> search(String text, int page, int pageSize, String... repositories) {
|
| | | if (StringUtils.isEmpty(text)) {
|
| | | return null;
|
| | | }
|
| | |
| | | searcher = new IndexSearcher(reader);
|
| | | }
|
| | | Query rewrittenQuery = searcher.rewrite(query);
|
| | | TopScoreDocCollector collector = TopScoreDocCollector.create(maximumHits, true);
|
| | | TopScoreDocCollector collector = TopScoreDocCollector.create(5000, true);
|
| | | searcher.search(rewrittenQuery, collector);
|
| | | ScoreDoc[] hits = collector.topDocs().scoreDocs;
|
| | | int offset = Math.max(0, (page - 1) * pageSize);
|
| | | ScoreDoc[] hits = collector.topDocs(offset, pageSize).scoreDocs;
|
| | | int totalHits = collector.getTotalHits();
|
| | | for (int i = 0; i < hits.length; i++) {
|
| | | int docId = hits[i].doc;
|
| | | Document doc = searcher.doc(docId);
|
| | | // TODO identify the source index for the doc, then eliminate FIELD_REPOSITORY |
| | | SearchResult result = createSearchResult(doc, hits[i].score);
|
| | | SearchResult result = createSearchResult(doc, hits[i].score, offset + i + 1, totalHits);
|
| | | if (repositories.length == 1) {
|
| | | // single repository search
|
| | | result.repository = repositories[0];
|