I noticed that if i do the get() before the maybeReopen then I get no results. But otherwise I can change it further.
On Mon, Mar 2, 2009 at 11:46 AM, Michael McCandless < luc...@mikemccandless.com> wrote: > > There is no such thing as final code -- code is alive and is always > changing ;) > > It looks good to me. > > Though one trivial thing is: I would move the code in the try clause up to > and including the multiSearcher=get() out above the try. I always attempt > to "shrink wrap" what's inside a try clause to the minimum that needs to be > there. Ie, your code that creates a query, finds the right sort & filter to > use, etc, can all happen outside the try, because you have not yet acquired > the multiSearcher. > > If you do that, you also don't need the null check in the finally clause, > because multiSearcher must be non-null on entering the try. > > Mike > > Amin Mohammed-Coleman wrote: > > Hi there >> Good morning! Here is the final search code: >> >> public Summary[] search(final SearchRequest searchRequest) >> throwsSearchExecutionException { >> >> final String searchTerm = searchRequest.getSearchTerm(); >> >> if (StringUtils.isBlank(searchTerm)) { >> >> throw new SearchExecutionException("Search string cannot be empty. There >> will be too many results to process."); >> >> } >> >> List<Summary> summaryList = new ArrayList<Summary>(); >> >> StopWatch stopWatch = new StopWatch("searchStopWatch"); >> >> stopWatch.start(); >> >> MultiSearcher multiSearcher = null; >> >> try { >> >> LOGGER.debug("Ensuring all index readers are up to date..."); >> >> maybeReopen(); >> >> Query query = queryParser.parse(searchTerm); >> >> LOGGER.debug("Search Term '" + searchTerm +"' ----> Lucene Query '" + >> query.toString() +"'"); >> >> Sort sort = null; >> >> sort = applySortIfApplicable(searchRequest); >> >> Filter[] filters =applyFiltersIfApplicable(searchRequest); >> >> ChainedFilter chainedFilter = null; >> >> if (filters != null) { >> >> chainedFilter = new ChainedFilter(filters, ChainedFilter.OR); >> >> } >> >> multiSearcher = get(); >> >> TopDocs topDocs = multiSearcher.search(query,chainedFilter ,100,sort); >> >> ScoreDoc[] scoreDocs = topDocs.scoreDocs; >> >> LOGGER.debug("total number of hits for [" + query.toString() + " ] = >> "+topDocs. >> totalHits); >> >> for (ScoreDoc scoreDoc : scoreDocs) { >> >> final Document doc = multiSearcher.doc(scoreDoc.doc); >> >> float score = scoreDoc.score; >> >> final BaseDocument baseDocument = new BaseDocument(doc, score); >> >> Summary documentSummary = new DocumentSummaryImpl(baseDocument); >> >> summaryList.add(documentSummary); >> >> } >> >> } catch (Exception e) { >> >> throw new IllegalStateException(e); >> >> } finally { >> >> if (multiSearcher != null) { >> >> release(multiSearcher); >> >> } >> >> } >> >> stopWatch.stop(); >> >> LOGGER.debug("total time taken for document seach: " + >> stopWatch.getTotalTimeMillis() + " ms"); >> >> return summaryList.toArray(new Summary[] {}); >> >> } >> >> >> >> I hope this makes sense...thanks again! >> >> >> Cheers >> >> Amin >> >> >> >> On Sun, Mar 1, 2009 at 8:09 PM, Michael McCandless < >> luc...@mikemccandless.com> wrote: >> >> >>> You're calling get() too many times. For every call to get() you must >>> match with a call to release(). >>> >>> So, once at the front of your search method you should: >>> >>> MultiSearcher searcher = get(); >>> >>> then use that searcher to do searching, retrieve docs, etc. >>> >>> Then in the finally clause, pass that searcher to release. >>> >>> So, only one call to get() and one matching call to release(). >>> >>> Mike >>> >>> Amin Mohammed-Coleman wrote: >>> >>> Hi >>> >>>> The searchers are injected into the class via Spring. So when a client >>>> calls the class it is fully configured with a list of index searchers. >>>> However I have removed this list and instead injecting a list of >>>> directories which are passed to the DocumentSearchManager. >>>> DocumentSearchManager is SearchManager (should've mentioned that >>>> earlier). >>>> So finally I have modified by release code to do the following: >>>> >>>> private void release(MultiSearcher multiSeacher) throws Exception { >>>> >>>> IndexSearcher[] indexSearchers = (IndexSearcher[]) >>>> multiSeacher.getSearchables(); >>>> >>>> for(int i =0 ; i < indexSearchers.length;i++) { >>>> >>>> documentSearcherManagers[i].release(indexSearchers[i]); >>>> >>>> } >>>> >>>> } >>>> >>>> >>>> and it's use looks like this: >>>> >>>> >>>> public Summary[] search(final SearchRequest searchRequest) >>>> throwsSearchExecutionException { >>>> >>>> final String searchTerm = searchRequest.getSearchTerm(); >>>> >>>> if (StringUtils.isBlank(searchTerm)) { >>>> >>>> throw new SearchExecutionException("Search string cannot be empty. There >>>> will be too many results to process."); >>>> >>>> } >>>> >>>> List<Summary> summaryList = new ArrayList<Summary>(); >>>> >>>> StopWatch stopWatch = new StopWatch("searchStopWatch"); >>>> >>>> stopWatch.start(); >>>> >>>> List<IndexSearcher> indexSearchers = new ArrayList<IndexSearcher>(); >>>> >>>> try { >>>> >>>> LOGGER.debug("Ensuring all index readers are up to date..."); >>>> >>>> maybeReopen(); >>>> >>>> LOGGER.debug("All Index Searchers are up to date. No of index searchers >>>> '" >>>> + >>>> indexSearchers.size() +"'"); >>>> >>>> Query query = queryParser.parse(searchTerm); >>>> >>>> LOGGER.debug("Search Term '" + searchTerm +"' ----> Lucene Query '" + >>>> query.toString() +"'"); >>>> >>>> Sort sort = null; >>>> >>>> sort = applySortIfApplicable(searchRequest); >>>> >>>> Filter[] filters =applyFiltersIfApplicable(searchRequest); >>>> >>>> ChainedFilter chainedFilter = null; >>>> >>>> if (filters != null) { >>>> >>>> chainedFilter = new ChainedFilter(filters, ChainedFilter.OR); >>>> >>>> } >>>> >>>> TopDocs topDocs = get().search(query,chainedFilter ,100,sort); >>>> >>>> ScoreDoc[] scoreDocs = topDocs.scoreDocs; >>>> >>>> LOGGER.debug("total number of hits for [" + query.toString() + " ] = >>>> "+topDocs. >>>> totalHits); >>>> >>>> for (ScoreDoc scoreDoc : scoreDocs) { >>>> >>>> final Document doc = get().doc(scoreDoc.doc); >>>> >>>> float score = scoreDoc.score; >>>> >>>> final BaseDocument baseDocument = new BaseDocument(doc, score); >>>> >>>> Summary documentSummary = new DocumentSummaryImpl(baseDocument); >>>> >>>> summaryList.add(documentSummary); >>>> >>>> } >>>> >>>> } catch (Exception e) { >>>> >>>> throw new IllegalStateException(e); >>>> >>>> } finally { >>>> >>>> release(get()); >>>> >>>> } >>>> >>>> stopWatch.stop(); >>>> >>>> LOGGER.debug("total time taken for document seach: " + >>>> stopWatch.getTotalTimeMillis() + " ms"); >>>> >>>> return summaryList.toArray(new Summary[] {}); >>>> >>>> } >>>> >>>> >>>> So the final post construct constructs the DocumentSearchMangers with >>>> the >>>> list of directories..looking like this >>>> >>>> >>>> @PostConstruct >>>> >>>> public void initialiseDocumentSearcher() { >>>> >>>> PerFieldAnalyzerWrapper analyzerWrapper = new PerFieldAnalyzerWrapper( >>>> analyzer); >>>> >>>> analyzerWrapper.addAnalyzer(FieldNameEnum.TYPE.getDescription(), >>>> newKeywordAnalyzer()); >>>> >>>> queryParser = >>>> newMultiFieldQueryParser(FieldNameEnum.fieldNameDescriptions(), >>>> analyzerWrapper); >>>> >>>> try { >>>> >>>> LOGGER.debug("Initialising multi searcher ...."); >>>> >>>> documentSearcherManagers = new >>>> DocumentSearcherManager[directories.size()]; >>>> >>>> for (int i = 0; i < directories.size() ;i++) { >>>> >>>> Directory directory = directories.get(i); >>>> >>>> DocumentSearcherManager documentSearcherManager = >>>> newDocumentSearcherManager(directory); >>>> >>>> documentSearcherManagers[i]=documentSearcherManager; >>>> >>>> } >>>> >>>> LOGGER.debug("multi searcher initialised"); >>>> >>>> } catch (IOException e) { >>>> >>>> throw new IllegalStateException(e); >>>> >>>> } >>>> >>>> } >>>> >>>> >>>> >>>> Cheers >>>> >>>> Amin >>>> >>>> >>>> >>>> On Sun, Mar 1, 2009 at 6:15 PM, Michael McCandless < >>>> luc...@mikemccandless.com> wrote: >>>> >>>> >>>> I don't understand where searchers comes from, prior to >>>>> initializeDocumentSearcher? You should, instead, simply create the >>>>> SearcherManager (from your Directory instances). You don't need any >>>>> searchers during initialize. >>>>> >>>>> Is DocumentSearcherManager the same as SearcherManager (just renamed)? >>>>> >>>>> The release method is wrong -- you're calling .get() and then >>>>> immediately release. Instead, you should step through the searchers >>>>> from your MultiSearcher and release them to each SearcherManager. >>>>> >>>>> You should call your release() in a finally clause. >>>>> >>>>> Mike >>>>> >>>>> Amin Mohammed-Coleman wrote: >>>>> >>>>> Sorry...i'm getting slightly confused. >>>>> >>>>> I have a PostConstruct which is where I should create an array of >>>>>> SearchManagers (per indexSeacher). From there I initialise the >>>>>> multisearcher using the get(). After which I need to call maybeReopen >>>>>> for >>>>>> each IndexSearcher. So I'll do the following: >>>>>> >>>>>> @PostConstruct >>>>>> >>>>>> public void initialiseDocumentSearcher() { >>>>>> >>>>>> PerFieldAnalyzerWrapper analyzerWrapper = new PerFieldAnalyzerWrapper( >>>>>> analyzer); >>>>>> >>>>>> analyzerWrapper.addAnalyzer(FieldNameEnum.TYPE.getDescription(), >>>>>> newKeywordAnalyzer()); >>>>>> >>>>>> queryParser = >>>>>> newMultiFieldQueryParser(FieldNameEnum.fieldNameDescriptions(), >>>>>> analyzerWrapper); >>>>>> >>>>>> try { >>>>>> >>>>>> LOGGER.debug("Initialising multi searcher ...."); >>>>>> >>>>>> documentSearcherManagers = new >>>>>> DocumentSearcherManager[searchers.size()]; >>>>>> >>>>>> for (int i = 0; i < searchers.size() ;i++) { >>>>>> >>>>>> IndexSearcher indexSearcher = searchers.get(i); >>>>>> >>>>>> Directory directory = indexSearcher.getIndexReader().directory(); >>>>>> >>>>>> DocumentSearcherManager documentSearcherManager = >>>>>> newDocumentSearcherManager(directory); >>>>>> >>>>>> documentSearcherManagers[i]=documentSearcherManager; >>>>>> >>>>>> } >>>>>> >>>>>> LOGGER.debug("multi searcher initialised"); >>>>>> >>>>>> } catch (IOException e) { >>>>>> >>>>>> throw new IllegalStateException(e); >>>>>> >>>>>> } >>>>>> >>>>>> } >>>>>> >>>>>> >>>>>> This initialises search managers. I then have methods: >>>>>> >>>>>> >>>>>> private void maybeReopen() throws Exception { >>>>>> >>>>>> LOGGER.debug("Initiating reopening of index readers..."); >>>>>> >>>>>> for (DocumentSearcherManager documentSearcherManager : >>>>>> documentSearcherManagers) { >>>>>> >>>>>> documentSearcherManager.maybeReopen(); >>>>>> >>>>>> } >>>>>> >>>>>> } >>>>>> >>>>>> >>>>>> >>>>>> private void release() throws Exception { >>>>>> >>>>>> for (DocumentSearcherManager documentSearcherManager : >>>>>> documentSearcherManagers) { >>>>>> >>>>>> documentSearcherManager.release(documentSearcherManager.get()); >>>>>> >>>>>> } >>>>>> >>>>>> } >>>>>> >>>>>> >>>>>> private MultiSearcher get() { >>>>>> >>>>>> List<IndexSearcher> listOfIndexSeachers = new >>>>>> ArrayList<IndexSearcher>(); >>>>>> >>>>>> for (DocumentSearcherManager documentSearcherManager : >>>>>> documentSearcherManagers) { >>>>>> >>>>>> listOfIndexSeachers.add(documentSearcherManager.get()); >>>>>> >>>>>> } >>>>>> >>>>>> try { >>>>>> >>>>>> multiSearcher = new >>>>>> MultiSearcher(listOfIndexSeachers.toArray(newIndexSearcher[] {})); >>>>>> >>>>>> } catch (IOException e) { >>>>>> >>>>>> throw new IllegalStateException(e); >>>>>> >>>>>> } >>>>>> >>>>>> return multiSearcher; >>>>>> >>>>>> } >>>>>> >>>>>> >>>>>> These methods are used in the following manner in the search code: >>>>>> >>>>>> >>>>>> public Summary[] search(final SearchRequest searchRequest) >>>>>> throwsSearchExecutionException { >>>>>> >>>>>> final String searchTerm = searchRequest.getSearchTerm(); >>>>>> >>>>>> if (StringUtils.isBlank(searchTerm)) { >>>>>> >>>>>> throw new SearchExecutionException("Search string cannot be empty. >>>>>> There >>>>>> will be too many results to process."); >>>>>> >>>>>> } >>>>>> >>>>>> List<Summary> summaryList = new ArrayList<Summary>(); >>>>>> >>>>>> StopWatch stopWatch = new StopWatch("searchStopWatch"); >>>>>> >>>>>> stopWatch.start(); >>>>>> >>>>>> List<IndexSearcher> indexSearchers = new ArrayList<IndexSearcher>(); >>>>>> >>>>>> try { >>>>>> >>>>>> LOGGER.debug("Ensuring all index readers are up to date..."); >>>>>> >>>>>> maybeReopen(); >>>>>> >>>>>> LOGGER.debug("All Index Searchers are up to date. No of index >>>>>> searchers >>>>>> '" >>>>>> + >>>>>> indexSearchers.size() +"'"); >>>>>> >>>>>> Query query = queryParser.parse(searchTerm); >>>>>> >>>>>> LOGGER.debug("Search Term '" + searchTerm +"' ----> Lucene Query '" + >>>>>> query.toString() +"'"); >>>>>> >>>>>> Sort sort = null; >>>>>> >>>>>> sort = applySortIfApplicable(searchRequest); >>>>>> >>>>>> Filter[] filters =applyFiltersIfApplicable(searchRequest); >>>>>> >>>>>> ChainedFilter chainedFilter = null; >>>>>> >>>>>> if (filters != null) { >>>>>> >>>>>> chainedFilter = new ChainedFilter(filters, ChainedFilter.OR); >>>>>> >>>>>> } >>>>>> >>>>>> TopDocs topDocs = get().search(query,chainedFilter ,100,sort); >>>>>> >>>>>> ScoreDoc[] scoreDocs = topDocs.scoreDocs; >>>>>> >>>>>> LOGGER.debug("total number of hits for [" + query.toString() + " ] = >>>>>> "+topDocs. >>>>>> totalHits); >>>>>> >>>>>> for (ScoreDoc scoreDoc : scoreDocs) { >>>>>> >>>>>> final Document doc = get().doc(scoreDoc.doc); >>>>>> >>>>>> float score = scoreDoc.score; >>>>>> >>>>>> final BaseDocument baseDocument = new BaseDocument(doc, score); >>>>>> >>>>>> Summary documentSummary = new DocumentSummaryImpl(baseDocument); >>>>>> >>>>>> summaryList.add(documentSummary); >>>>>> >>>>>> } >>>>>> >>>>>> release(); >>>>>> >>>>>> } catch (Exception e) { >>>>>> >>>>>> throw new IllegalStateException(e); >>>>>> >>>>>> } >>>>>> >>>>>> stopWatch.stop(); >>>>>> >>>>>> LOGGER.debug("total time taken for document seach: " + >>>>>> stopWatch.getTotalTimeMillis() + " ms"); >>>>>> >>>>>> return summaryList.toArray(new Summary[] {}); >>>>>> >>>>>> } >>>>>> >>>>>> >>>>>> Does this look better? Again..I really really appreciate your help! >>>>>> >>>>>> >>>>>> On Sun, Mar 1, 2009 at 4:18 PM, Michael McCandless < >>>>>> luc...@mikemccandless.com> wrote: >>>>>> >>>>>> >>>>>> This is not quite right -- you should only create SearcherManager once >>>>>> >>>>>>> (per Direcotry) at startup/app load, not with every search request. >>>>>>> >>>>>>> And I don't see release -- it must call SearcherManager.release of >>>>>>> each of the IndexSearchers previously returned from get(). >>>>>>> >>>>>>> Mike >>>>>>> >>>>>>> Amin Mohammed-Coleman wrote: >>>>>>> >>>>>>> Hi >>>>>>> >>>>>>> Thanks again for helping on a Sunday! >>>>>>> >>>>>>>> >>>>>>>> I have now modified my maybeOpen() to do the following: >>>>>>>> >>>>>>>> private void maybeReopen() throws Exception { >>>>>>>> >>>>>>>> LOGGER.debug("Initiating reopening of index readers..."); >>>>>>>> >>>>>>>> IndexSearcher[] indexSearchers = (IndexSearcher[]) multiSearcher >>>>>>>> .getSearchables(); >>>>>>>> >>>>>>>> for (IndexSearcher indexSearcher : indexSearchers) { >>>>>>>> >>>>>>>> IndexReader indexReader = indexSearcher.getIndexReader(); >>>>>>>> >>>>>>>> SearcherManager documentSearcherManager = new >>>>>>>> SearcherManager(indexReader.directory()); >>>>>>>> >>>>>>>> documentSearcherManager.maybeReopen(); >>>>>>>> >>>>>>>> } >>>>>>>> >>>>>>>> } >>>>>>>> >>>>>>>> >>>>>>>> And get() to: >>>>>>>> >>>>>>>> >>>>>>>> private synchronized MultiSearcher get() { >>>>>>>> >>>>>>>> IndexSearcher[] indexSearchers = (IndexSearcher[]) multiSearcher >>>>>>>> .getSearchables(); >>>>>>>> >>>>>>>> List<IndexSearcher> indexSearchersList = new >>>>>>>> ArrayList<IndexSearcher>(); >>>>>>>> >>>>>>>> for (IndexSearcher indexSearcher : indexSearchers) { >>>>>>>> >>>>>>>> IndexReader indexReader = indexSearcher.getIndexReader(); >>>>>>>> >>>>>>>> SearcherManager documentSearcherManager = null; >>>>>>>> >>>>>>>> try { >>>>>>>> >>>>>>>> documentSearcherManager = new >>>>>>>> SearcherManager(indexReader.directory()); >>>>>>>> >>>>>>>> } catch (IOException e) { >>>>>>>> >>>>>>>> throw new IllegalStateException(e); >>>>>>>> >>>>>>>> } >>>>>>>> >>>>>>>> indexSearchersList.add(documentSearcherManager.get()); >>>>>>>> >>>>>>>> } >>>>>>>> >>>>>>>> try { >>>>>>>> >>>>>>>> multiSearcher = new >>>>>>>> MultiSearcher(indexSearchersList.toArray(newIndexSearcher[] {})); >>>>>>>> >>>>>>>> } catch (IOException e) { >>>>>>>> >>>>>>>> throw new IllegalStateException(e); >>>>>>>> >>>>>>>> } >>>>>>>> >>>>>>>> return multiSearcher; >>>>>>>> >>>>>>>> } >>>>>>>> >>>>>>>> >>>>>>>> >>>>>>>> This makes all my test pass. I am using the SearchManager that you >>>>>>>> recommended. Does this look ok? >>>>>>>> >>>>>>>> >>>>>>>> On Sun, Mar 1, 2009 at 2:38 PM, Michael McCandless < >>>>>>>> luc...@mikemccandless.com> wrote: >>>>>>>> >>>>>>>> Your maybeReopen has an excess incRef(). >>>>>>>> >>>>>>>> >>>>>>>> I'm not sure how you open the searchers in the first place? The >>>>>>>>> list >>>>>>>>> starts as empty, and nothing populates it? >>>>>>>>> >>>>>>>>> When you do the initial population, you need an incRef. >>>>>>>>> >>>>>>>>> I think you're hitting IllegalStateException because maybeReopen is >>>>>>>>> closing a reader before get() can get it (since they synchronize on >>>>>>>>> different objects). >>>>>>>>> >>>>>>>>> I'd recommend switching to the SearcherManager class. Instantiate >>>>>>>>> one >>>>>>>>> for each of your searchers. On each search request, go through >>>>>>>>> them >>>>>>>>> and call maybeReopen(), and then call get() and gather each >>>>>>>>> IndexSearcher instance into a new array. Then, make a new >>>>>>>>> MultiSearcher (opposite of what I said before): while that creates >>>>>>>>> a >>>>>>>>> small amount of garbage, it'll keep your code simpler (good >>>>>>>>> tradeoff). >>>>>>>>> >>>>>>>>> Mike >>>>>>>>> >>>>>>>>> Amin Mohammed-Coleman wrote: >>>>>>>>> >>>>>>>>> sorrry I added >>>>>>>>> >>>>>>>>> >>>>>>>>> release(multiSearcher); >>>>>>>>> >>>>>>>>>> >>>>>>>>>> >>>>>>>>>> instead of multiSearcher.close(); >>>>>>>>>> >>>>>>>>>> On Sun, Mar 1, 2009 at 2:17 PM, Amin Mohammed-Coleman < >>>>>>>>>> ami...@gmail.com >>>>>>>>>> >>>>>>>>>> wrote: >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Hi >>>>>>>>>>> >>>>>>>>>> >>>>>>>>>> I've now done the following: >>>>>>>>>> >>>>>>>>>> >>>>>>>>>>> public Summary[] search(final SearchRequest searchRequest) >>>>>>>>>>> throwsSearchExecutionException { >>>>>>>>>>> >>>>>>>>>>> final String searchTerm = searchRequest.getSearchTerm(); >>>>>>>>>>> >>>>>>>>>>> if (StringUtils.isBlank(searchTerm)) { >>>>>>>>>>> >>>>>>>>>>> throw new SearchExecutionException("Search string cannot be >>>>>>>>>>> empty. >>>>>>>>>>> There >>>>>>>>>>> will be too many results to process."); >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> List<Summary> summaryList = new ArrayList<Summary>(); >>>>>>>>>>> >>>>>>>>>>> StopWatch stopWatch = new StopWatch("searchStopWatch"); >>>>>>>>>>> >>>>>>>>>>> stopWatch.start(); >>>>>>>>>>> >>>>>>>>>>> List<IndexSearcher> indexSearchers = new >>>>>>>>>>> ArrayList<IndexSearcher>(); >>>>>>>>>>> >>>>>>>>>>> try { >>>>>>>>>>> >>>>>>>>>>> LOGGER.debug("Ensuring all index readers are up to date..."); >>>>>>>>>>> >>>>>>>>>>> maybeReopen(); >>>>>>>>>>> >>>>>>>>>>> LOGGER.debug("All Index Searchers are up to date. No of index >>>>>>>>>>> searchers >>>>>>>>>>> '"+ indexSearchers.size() + >>>>>>>>>>> "'"); >>>>>>>>>>> >>>>>>>>>>> Query query = queryParser.parse(searchTerm); >>>>>>>>>>> >>>>>>>>>>> LOGGER.debug("Search Term '" + searchTerm +"' ----> Lucene Query >>>>>>>>>>> '" >>>>>>>>>>> + >>>>>>>>>>> query.toString() +"'"); >>>>>>>>>>> >>>>>>>>>>> Sort sort = null; >>>>>>>>>>> >>>>>>>>>>> sort = applySortIfApplicable(searchRequest); >>>>>>>>>>> >>>>>>>>>>> Filter[] filters =applyFiltersIfApplicable(searchRequest); >>>>>>>>>>> >>>>>>>>>>> ChainedFilter chainedFilter = null; >>>>>>>>>>> >>>>>>>>>>> if (filters != null) { >>>>>>>>>>> >>>>>>>>>>> chainedFilter = new ChainedFilter(filters, ChainedFilter.OR); >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> TopDocs topDocs = get().search(query,chainedFilter ,100,sort); >>>>>>>>>>> >>>>>>>>>>> ScoreDoc[] scoreDocs = topDocs.scoreDocs; >>>>>>>>>>> >>>>>>>>>>> LOGGER.debug("total number of hits for [" + query.toString() + " >>>>>>>>>>> ] >>>>>>>>>>> = >>>>>>>>>>> "+topDocs. >>>>>>>>>>> totalHits); >>>>>>>>>>> >>>>>>>>>>> for (ScoreDoc scoreDoc : scoreDocs) { >>>>>>>>>>> >>>>>>>>>>> final Document doc = multiSearcher.doc(scoreDoc.doc); >>>>>>>>>>> >>>>>>>>>>> float score = scoreDoc.score; >>>>>>>>>>> >>>>>>>>>>> final BaseDocument baseDocument = new BaseDocument(doc, score); >>>>>>>>>>> >>>>>>>>>>> Summary documentSummary = new DocumentSummaryImpl(baseDocument); >>>>>>>>>>> >>>>>>>>>>> summaryList.add(documentSummary); >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> multiSearcher.close(); >>>>>>>>>>> >>>>>>>>>>> } catch (Exception e) { >>>>>>>>>>> >>>>>>>>>>> throw new IllegalStateException(e); >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> stopWatch.stop(); >>>>>>>>>>> >>>>>>>>>>> LOGGER.debug("total time taken for document seach: " + >>>>>>>>>>> stopWatch.getTotalTimeMillis() + " ms"); >>>>>>>>>>> >>>>>>>>>>> return summaryList.toArray(new Summary[] {}); >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> And have the following methods: >>>>>>>>>>> >>>>>>>>>>> @PostConstruct >>>>>>>>>>> >>>>>>>>>>> public void initialiseQueryParser() { >>>>>>>>>>> >>>>>>>>>>> PerFieldAnalyzerWrapper analyzerWrapper = new >>>>>>>>>>> PerFieldAnalyzerWrapper( >>>>>>>>>>> analyzer); >>>>>>>>>>> >>>>>>>>>>> analyzerWrapper.addAnalyzer(FieldNameEnum.TYPE.getDescription(), >>>>>>>>>>> newKeywordAnalyzer()); >>>>>>>>>>> >>>>>>>>>>> queryParser = >>>>>>>>>>> newMultiFieldQueryParser(FieldNameEnum.fieldNameDescriptions(), >>>>>>>>>>> >>>>>>>>>>> analyzerWrapper); >>>>>>>>>>> >>>>>>>>>>> try { >>>>>>>>>>> >>>>>>>>>>> LOGGER.debug("Initialising multi searcher ...."); >>>>>>>>>>> >>>>>>>>>>> this.multiSearcher = new >>>>>>>>>>> MultiSearcher(searchers.toArray(newIndexSearcher[] {})); >>>>>>>>>>> >>>>>>>>>>> LOGGER.debug("multi searcher initialised"); >>>>>>>>>>> >>>>>>>>>>> } catch (IOException e) { >>>>>>>>>>> >>>>>>>>>>> throw new IllegalStateException(e); >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Initialises mutltisearcher when this class is creared by spring. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> private synchronized void swapMultiSearcher(MultiSearcher >>>>>>>>>>> newMultiSearcher) { >>>>>>>>>>> >>>>>>>>>>> try { >>>>>>>>>>> >>>>>>>>>>> release(multiSearcher); >>>>>>>>>>> >>>>>>>>>>> } catch (IOException e) { >>>>>>>>>>> >>>>>>>>>>> throw new IllegalStateException(e); >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> multiSearcher = newMultiSearcher; >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> public void maybeReopen() throws IOException { >>>>>>>>>>> >>>>>>>>>>> MultiSearcher newMultiSeacher = null; >>>>>>>>>>> >>>>>>>>>>> boolean refreshMultiSeacher = false; >>>>>>>>>>> >>>>>>>>>>> List<IndexSearcher> indexSearchers = new >>>>>>>>>>> ArrayList<IndexSearcher>(); >>>>>>>>>>> >>>>>>>>>>> synchronized (searchers) { >>>>>>>>>>> >>>>>>>>>>> for (IndexSearcher indexSearcher: searchers) { >>>>>>>>>>> >>>>>>>>>>> IndexReader reader = indexSearcher.getIndexReader(); >>>>>>>>>>> >>>>>>>>>>> reader.incRef(); >>>>>>>>>>> >>>>>>>>>>> Directory directory = reader.directory(); >>>>>>>>>>> >>>>>>>>>>> long currentVersion = reader.getVersion(); >>>>>>>>>>> >>>>>>>>>>> if (IndexReader.getCurrentVersion(directory) != currentVersion) { >>>>>>>>>>> >>>>>>>>>>> IndexReader newReader = indexSearcher.getIndexReader().reopen(); >>>>>>>>>>> >>>>>>>>>>> if (newReader != reader) { >>>>>>>>>>> >>>>>>>>>>> reader.decRef(); >>>>>>>>>>> >>>>>>>>>>> refreshMultiSeacher = true; >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> reader = newReader; >>>>>>>>>>> >>>>>>>>>>> IndexSearcher newSearcher = new IndexSearcher(newReader); >>>>>>>>>>> >>>>>>>>>>> indexSearchers.add(newSearcher); >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> if (refreshMultiSeacher) { >>>>>>>>>>> >>>>>>>>>>> newMultiSeacher = new >>>>>>>>>>> MultiSearcher(indexSearchers.toArray(newIndexSearcher[] {})); >>>>>>>>>>> >>>>>>>>>>> warm(newMultiSeacher); >>>>>>>>>>> >>>>>>>>>>> swapMultiSearcher(newMultiSeacher); >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> private void warm(MultiSearcher newMultiSeacher) { >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> private synchronized MultiSearcher get() { >>>>>>>>>>> >>>>>>>>>>> for (IndexSearcher indexSearcher: searchers) { >>>>>>>>>>> >>>>>>>>>>> indexSearcher.getIndexReader().incRef(); >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> return multiSearcher; >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> private synchronized void release(MultiSearcher multiSearcher) >>>>>>>>>>> throwsIOException { >>>>>>>>>>> >>>>>>>>>>> for (IndexSearcher indexSearcher: searchers) { >>>>>>>>>>> >>>>>>>>>>> indexSearcher.getIndexReader().decRef(); >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> However I am now getting >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> java.lang.IllegalStateException: >>>>>>>>>>> org.apache.lucene.store.AlreadyClosedException: this IndexReader >>>>>>>>>>> is >>>>>>>>>>> closed >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> on the call: >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> private synchronized MultiSearcher get() { >>>>>>>>>>> >>>>>>>>>>> for (IndexSearcher indexSearcher: searchers) { >>>>>>>>>>> >>>>>>>>>>> indexSearcher.getIndexReader().incRef(); >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> return multiSearcher; >>>>>>>>>>> >>>>>>>>>>> } >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> I'm doing something wrong ..obviously..not sure where though.. >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> Cheers >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> On Sun, Mar 1, 2009 at 1:36 PM, Michael McCandless < >>>>>>>>>>> luc...@mikemccandless.com> wrote: >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> I was wondering the same thing ;) >>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> It's best to call this method from a single BG "warming" thread, >>>>>>>>>>>> in >>>>>>>>>>>> which >>>>>>>>>>>> case it would not need its own synchronization. >>>>>>>>>>>> >>>>>>>>>>>> But, to be safe, I'll add internal synchronization to it. You >>>>>>>>>>>> can't >>>>>>>>>>>> simply put synchronized in front of the method, since you don't >>>>>>>>>>>> want >>>>>>>>>>>> this to >>>>>>>>>>>> block searching. >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> Mike >>>>>>>>>>>> >>>>>>>>>>>> Amin Mohammed-Coleman wrote: >>>>>>>>>>>> >>>>>>>>>>>> just a quick point: >>>>>>>>>>>> >>>>>>>>>>>> public void maybeReopen() throws IOException { >>>>>>>>>>>> //D >>>>>>>>>>>> >>>>>>>>>>>> long currentVersion = >>>>>>>>>>>> >>>>>>>>>>>>> currentSearcher.getIndexReader().getVersion(); >>>>>>>>>>>>> if (IndexReader.getCurrentVersion(dir) != currentVersion) { >>>>>>>>>>>>> IndexReader newReader = >>>>>>>>>>>>> currentSearcher.getIndexReader().reopen(); >>>>>>>>>>>>> assert newReader != currentSearcher.getIndexReader(); >>>>>>>>>>>>> IndexSearcher newSearcher = new IndexSearcher(newReader); >>>>>>>>>>>>> warm(newSearcher); >>>>>>>>>>>>> swapSearcher(newSearcher); >>>>>>>>>>>>> } >>>>>>>>>>>>> } >>>>>>>>>>>>> >>>>>>>>>>>>> should the above be synchronised? >>>>>>>>>>>>> >>>>>>>>>>>>> On Sun, Mar 1, 2009 at 1:25 PM, Amin Mohammed-Coleman < >>>>>>>>>>>>> ami...@gmail.com >>>>>>>>>>>>> >>>>>>>>>>>>> wrote: >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>> >>>>>>>>>>>>>> thanks. i will rewrite..in between giving my baby her feed >>>>>>>>>>>>>> and >>>>>>>>>>>>>> >>>>>>>>>>>>>> playing >>>>>>>>>>>>> >>>>>>>>>>>>> with the other child and my wife who wants me to do several >>>>>>>>>>>>> other >>>>>>>>>>>>> >>>>>>>>>>>>> things! >>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> On Sun, Mar 1, 2009 at 1:20 PM, Michael McCandless < >>>>>>>>>>>>>> luc...@mikemccandless.com> wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Amin Mohammed-Coleman wrote: >>>>>>>>>>>>>> >>>>>>>>>>>>>> >>>>>>>>>>>>>> Hi >>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> Thanks for your input. I would like to have a go at doing >>>>>>>>>>>>>>> this >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> myself >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> first, Solr may be an option. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> * You are creating a new Analyzer & QueryParser every time, >>>>>>>>>>>>>>>> also >>>>>>>>>>>>>>>> creating unnecessary garbage; instead, they should be >>>>>>>>>>>>>>>> created >>>>>>>>>>>>>>>> once >>>>>>>>>>>>>>>> & reused. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- I can moved the code out so that it is only created once >>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>> reused. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> * You always make a new IndexSearcher and a new >>>>>>>>>>>>>>>> MultiSearcher >>>>>>>>>>>>>>>> even >>>>>>>>>>>>>>>> when nothing has changed. This just generates unnecessary >>>>>>>>>>>>>>>> garbage >>>>>>>>>>>>>>>> which GC then must sweep up. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> -- This was something I thought about. I could move it out >>>>>>>>>>>>>>>> so >>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>> it's >>>>>>>>>>>>>>>> created once. However I presume inside my code i need to >>>>>>>>>>>>>>>> check >>>>>>>>>>>>>>>> whether >>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>> indexreaders are update to date. This needs to be >>>>>>>>>>>>>>>> synchronized >>>>>>>>>>>>>>>> as >>>>>>>>>>>>>>>> well I >>>>>>>>>>>>>>>> guess(?) >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Yes you should synchronize the check for whether the >>>>>>>>>>>>>>>> IndexReader >>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> current. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> * I don't see any synchronization -- it looks like two search >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> requests are allowed into this method at the same time? >>>>>>>>>>>>>>> Which >>>>>>>>>>>>>>> is >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> dangerous... eg both (or, more) will wastefully reopen the >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> readers. >>>>>>>>>>>>>>>> -- So i need to extract the logic for reopening and provide >>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>> synchronisation mechanism. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Yes. >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> Ok. So I have some work to do. I'll refactor the code and >>>>>>>>>>>>>>> see >>>>>>>>>>>>>>> if >>>>>>>>>>>>>>> I >>>>>>>>>>>>>>> can >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> get >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> inline to your recommendations. >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On Sun, Mar 1, 2009 at 12:11 PM, Michael McCandless < >>>>>>>>>>>>>>>> luc...@mikemccandless.com> wrote: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> On a quick look, I think there are a few problems with the >>>>>>>>>>>>>>>> code: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> * I don't see any synchronization -- it looks like two >>>>>>>>>>>>>>>> search >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> requests are allowed into this method at the same time? >>>>>>>>>>>>>>>>> Which >>>>>>>>>>>>>>>>> is >>>>>>>>>>>>>>>>> dangerous... eg both (or, more) will wastefully reopen the >>>>>>>>>>>>>>>>> readers. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> * You are over-incRef'ing (the reader.incRef inside the >>>>>>>>>>>>>>>>> loop) >>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>> I >>>>>>>>>>>>>>>>> don't see a corresponding decRef. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> * You reopen and warm your searchers "live" (vs with BG >>>>>>>>>>>>>>>>> thread); >>>>>>>>>>>>>>>>> meaning the unlucky search request that hits a reopen pays >>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>> cost. This might be OK if the index is small enough that >>>>>>>>>>>>>>>>> reopening & warming takes very little time. But if index >>>>>>>>>>>>>>>>> gets >>>>>>>>>>>>>>>>> large, making a random search pay that warming cost is not >>>>>>>>>>>>>>>>> nice >>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>> the end user. It erodes their trust in you. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> * You always make a new IndexSearcher and a new >>>>>>>>>>>>>>>>> MultiSearcher >>>>>>>>>>>>>>>>> even >>>>>>>>>>>>>>>>> when nothing has changed. This just generates unnecessary >>>>>>>>>>>>>>>>> garbage >>>>>>>>>>>>>>>>> which GC then must sweep up. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> * You are creating a new Analyzer & QueryParser every time, >>>>>>>>>>>>>>>>> also >>>>>>>>>>>>>>>>> creating unnecessary garbage; instead, they should be >>>>>>>>>>>>>>>>> created >>>>>>>>>>>>>>>>> once >>>>>>>>>>>>>>>>> & reused. >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> You should consider simply using Solr -- it handles all >>>>>>>>>>>>>>>>> this >>>>>>>>>>>>>>>>> logic >>>>>>>>>>>>>>>>> for >>>>>>>>>>>>>>>>> you and has been well debugged with time... >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Mike >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> Amin Mohammed-Coleman wrote: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> The reason for the indexreader.reopen is because I have a >>>>>>>>>>>>>>>>> webapp >>>>>>>>>>>>>>>>> which >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> enables users to upload files and then search for the >>>>>>>>>>>>>>>>> documents. >>>>>>>>>>>>>>>>> If >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> I >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> don't >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> reopen i'm concerned that the facet hit counter won't be >>>>>>>>>>>>>>>>>> updated. >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> On Tue, Feb 24, 2009 at 8:32 PM, Amin Mohammed-Coleman < >>>>>>>>>>>>>>>>>> ami...@gmail.com >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> I have been able to get the code working for my scenario, >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> however >>>>>>>>>>>>>>>>>> I >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> have >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> question and I was wondering if I could get some help. I >>>>>>>>>>>>>>>>>>> have >>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>> list >>>>>>>>>>>>>>>>>>> of >>>>>>>>>>>>>>>>>>> IndexSearchers which are used in a MultiSearcher class. >>>>>>>>>>>>>>>>>>> I >>>>>>>>>>>>>>>>>>> use >>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>> indexsearchers to get each indexreader and put them into >>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>> MultiIndexReader. >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> IndexReader[] readers = new >>>>>>>>>>>>>>>>>>> IndexReader[searchables.length]; >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> for (int i =0 ; i < searchables.length;i++) { >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> IndexSearcher indexSearcher = >>>>>>>>>>>>>>>>>>> (IndexSearcher)searchables[i]; >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> readers[i] = indexSearcher.getIndexReader(); >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> IndexReader newReader = readers[i].reopen(); >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> if (newReader != readers[i]) { >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> readers[i].close(); >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> readers[i] = newReader; >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> } >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> multiReader = new MultiReader(readers); >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> OpenBitSetFacetHitCounter facetHitCounter = >>>>>>>>>>>>>>>>>>> newOpenBitSetFacetHitCounter(); >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> IndexSearcher indexSearcher = new >>>>>>>>>>>>>>>>>>> IndexSearcher(multiReader); >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> I then use the indexseacher to do the facet stuff. I end >>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>> code >>>>>>>>>>>>>>>>>>> with >>>>>>>>>>>>>>>>>>> closing the multireader. This is causing problems in >>>>>>>>>>>>>>>>>>> another >>>>>>>>>>>>>>>>>>> method >>>>>>>>>>>>>>>>>>> where I >>>>>>>>>>>>>>>>>>> do some other search as the indexreaders are closed. Is >>>>>>>>>>>>>>>>>>> it >>>>>>>>>>>>>>>>>>> ok >>>>>>>>>>>>>>>>>>> to >>>>>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>>>>> close >>>>>>>>>>>>>>>>>>> the multiindexreader or should I do some additional >>>>>>>>>>>>>>>>>>> checks >>>>>>>>>>>>>>>>>>> in >>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>> other >>>>>>>>>>>>>>>>>>> method to see if the indexreader is closed? >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Cheers >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> P.S. Hope that made sense...! >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> On Mon, Feb 23, 2009 at 7:20 AM, Amin Mohammed-Coleman < >>>>>>>>>>>>>>>>>>> ami...@gmail.com >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Thanks just what I needed! >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> Cheers >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Amin >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> On 22 Feb 2009, at 16:11, Marcelo Ochoa < >>>>>>>>>>>>>>>>>>>> marcelo.oc...@gmail.com> >>>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Hi Amin: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> Please take a look a this blog post: >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> http://sujitpal.blogspot.com/2007/04/lucene-search-within-search-with.html >>>>>>>>>>>>>>>>>>>>> Best regards, Marcelo. >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> On Sun, Feb 22, 2009 at 1:18 PM, Amin Mohammed-Coleman >>>>>>>>>>>>>>>>>>>>> < >>>>>>>>>>>>>>>>>>>>> ami...@gmail.com> >>>>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> Sorry to re send this email but I was wondering if I >>>>>>>>>>>>>>>>>>>>> could >>>>>>>>>>>>>>>>>>>>> get >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> some >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> advice >>>>>>>>>>>>>>>>>>>>>> on this. >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Cheers >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Amin >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> On 16 Feb 2009, at 20:37, Amin Mohammed-Coleman < >>>>>>>>>>>>>>>>>>>>>> ami...@gmail.com> >>>>>>>>>>>>>>>>>>>>>> wrote: >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Hi >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> I am looking at building a faceted search using >>>>>>>>>>>>>>>>>>>>>> Lucene. >>>>>>>>>>>>>>>>>>>>>> I >>>>>>>>>>>>>>>>>>>>>> know >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> Solr >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> comes with this built in, however I would like to try >>>>>>>>>>>>>>>>>>>>>>> this >>>>>>>>>>>>>>>>>>>>>>> by >>>>>>>>>>>>>>>>>>>>>>> myself >>>>>>>>>>>>>>>>>>>>>>> (something to add to my CV!). I have been looking >>>>>>>>>>>>>>>>>>>>>>> around >>>>>>>>>>>>>>>>>>>>>>> and >>>>>>>>>>>>>>>>>>>>>>> I >>>>>>>>>>>>>>>>>>>>>>> found >>>>>>>>>>>>>>>>>>>>>>> that >>>>>>>>>>>>>>>>>>>>>>> you can use the IndexReader and use TermVectors. >>>>>>>>>>>>>>>>>>>>>>> This >>>>>>>>>>>>>>>>>>>>>>> looks >>>>>>>>>>>>>>>>>>>>>>> ok >>>>>>>>>>>>>>>>>>>>>>> but >>>>>>>>>>>>>>>>>>>>>>> I'm >>>>>>>>>>>>>>>>>>>>>>> not >>>>>>>>>>>>>>>>>>>>>>> sure how to filter the results so that a particular >>>>>>>>>>>>>>>>>>>>>>> user >>>>>>>>>>>>>>>>>>>>>>> can >>>>>>>>>>>>>>>>>>>>>>> only >>>>>>>>>>>>>>>>>>>>>>> see >>>>>>>>>>>>>>>>>>>>>>> a >>>>>>>>>>>>>>>>>>>>>>> subset of results. The next option I was looking at >>>>>>>>>>>>>>>>>>>>>>> was >>>>>>>>>>>>>>>>>>>>>>> something >>>>>>>>>>>>>>>>>>>>>>> like >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Term term1 = new Term("brand", "ford"); >>>>>>>>>>>>>>>>>>>>>>> Term term2 = new Term("brand", "vw"); >>>>>>>>>>>>>>>>>>>>>>> Term[] termsArray = new Term[] { term1, term2 };un >>>>>>>>>>>>>>>>>>>>>>> int[] docFreqs = indexSearcher.docFreqs(termsArray); >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> The only problem here is that I have to provide the >>>>>>>>>>>>>>>>>>>>>>> brand >>>>>>>>>>>>>>>>>>>>>>> type >>>>>>>>>>>>>>>>>>>>>>> each >>>>>>>>>>>>>>>>>>>>>>> time a >>>>>>>>>>>>>>>>>>>>>>> new brand is created. Again I'm not sure how I can >>>>>>>>>>>>>>>>>>>>>>> filter >>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>> results >>>>>>>>>>>>>>>>>>>>>>> here. >>>>>>>>>>>>>>>>>>>>>>> It may be that I'm using the wrong api methods to do >>>>>>>>>>>>>>>>>>>>>>> this. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> I would be grateful if I could get some advice on >>>>>>>>>>>>>>>>>>>>>>> this. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Cheers >>>>>>>>>>>>>>>>>>>>>>> Amin >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> P.S. I am basically trying to do something that >>>>>>>>>>>>>>>>>>>>>>> displays >>>>>>>>>>>>>>>>>>>>>>> the >>>>>>>>>>>>>>>>>>>>>>> following >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Personal Contact (23) Business Contact (45) and so >>>>>>>>>>>>>>>>>>>>>>> on.. >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> -- >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>> Marcelo F. Ochoa >>>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>> http://marceloochoa.blogspot.com/ >>>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> http://marcelo.ochoa.googlepages.com/home >>>>>>>>>>>>>>>>>>>>> ______________ >>>>>>>>>>>>>>>>>>>>> Want to integrate Lucene and Oracle? >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> http://marceloochoa.blogspot.com/2007/09/running-lucene-inside-your-oracle-jvm.html >>>>>>>>>>>>>>>>>>>>> Is Oracle 11g REST ready? >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> http://marceloochoa.blogspot.com/2008/02/is-oracle-11g-rest-ready.html >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> --------------------------------------------------------------------- >>>>>>>>>>>>>>>>>>>>> To unsubscribe, e-mail: >>>>>>>>>>>>>>>>>>>>> java-user-unsubscr...@lucene.apache.org >>>>>>>>>>>>>>>>>>>>> For additional commands, e-mail: >>>>>>>>>>>>>>>>>>>>> java-user-h...@lucene.apache.org >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> --------------------------------------------------------------------- >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>> To unsubscribe, e-mail: >>>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>> java-user-unsubscr...@lucene.apache.org >>>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> For additional commands, e-mail: >>>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>> java-user-h...@lucene.apache.org >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> --------------------------------------------------------------------- >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> To unsubscribe, e-mail: >>>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>>> java-user-unsubscr...@lucene.apache.org >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>>> For additional commands, e-mail: >>>>>>>>>>>>>>>> >>>>>>>>>>>>>>> java-user-h...@lucene.apache.org >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> --------------------------------------------------------------------- >>>>>>>>>>>>>>> >>>>>>>>>>>>>>> >>>>>>>>>>>>>> To unsubscribe, e-mail: >>>>>>>>>>>>>> >>>>>>>>>>>>> java-user-unsubscr...@lucene.apache.org >>>>>>>>>>>>> >>>>>>>>>>>>> For additional commands, e-mail: >>>>>>>>>>>> java-user-h...@lucene.apache.org >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> >>>>>>>>>>>> --------------------------------------------------------------------- >>>>>>>>>>>> >>>>>>>>>>> >>>>>>>>>>> To unsubscribe, e-mail: java-user-unsubscr...@lucene.apache.org >>>>>>>>>> >>>>>>>>> For additional commands, e-mail: java-user-h...@lucene.apache.org >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> >>>>>>>>> --------------------------------------------------------------------- >>>>>>>>> >>>>>>>> To unsubscribe, e-mail: java-user-unsubscr...@lucene.apache.org >>>>>>> For additional commands, e-mail: java-user-h...@lucene.apache.org >>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> --------------------------------------------------------------------- >>>>> To unsubscribe, e-mail: java-user-unsubscr...@lucene.apache.org >>>>> For additional commands, e-mail: java-user-h...@lucene.apache.org >>>>> >>>>> >>>>> >>>>> >>> --------------------------------------------------------------------- >>> To unsubscribe, e-mail: java-user-unsubscr...@lucene.apache.org >>> For additional commands, e-mail: java-user-h...@lucene.apache.org >>> >>> >>> > > --------------------------------------------------------------------- > To unsubscribe, e-mail: java-user-unsubscr...@lucene.apache.org > For additional commands, e-mail: java-user-h...@lucene.apache.org > >