View Javadoc
1   /*
2    * The baseCode project
3    *
4    * Copyright (c) 2013 University of British Columbia
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    * http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
12   * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
13   * specific language governing permissions and limitations under the License.
14   */
15  package ubic.basecode.ontology.jena.search;
16  
17  import com.hp.hpl.jena.util.iterator.Map1;
18  import com.hp.hpl.jena.util.iterator.Map1Iterator;
19  import org.apache.jena.larq.ARQLuceneException;
20  import org.apache.jena.larq.HitLARQ;
21  import org.apache.jena.larq.IndexLARQ;
22  import org.apache.jena.larq.LARQ;
23  import org.apache.lucene.analysis.Analyzer;
24  import org.apache.lucene.index.IndexReader;
25  import org.apache.lucene.index.MultiReader;
26  import org.apache.lucene.search.IndexSearcher;
27  import org.apache.lucene.search.Query;
28  import org.apache.lucene.search.ScoreDoc;
29  import org.apache.lucene.search.TopDocs;
30  
31  import java.io.IOException;
32  import java.util.Arrays;
33  import java.util.Iterator;
34  
35  /**
36   * Customization to deal with MultiReader and 'open' while indexing is going on ...? Might not be needed.
37   *
38   * @author Paul
39   */
40  public class SearchIndex extends IndexLARQ {
41  
42      public SearchIndex( IndexReader r ) {
43          super( r );
44      }
45  
46      public SearchIndex( MultiReader r, Analyzer a ) {
47          super( r, a );
48      }
49  
50      @SuppressWarnings("resource")
51      @Override
52      public Iterator<HitLARQ> search( String queryString ) {
53          try {
54              final IndexSearcher s = getIndexSearcher();
55              Query query = getLuceneQueryParser().parse( queryString );
56  
57              TopDocs topDocs = s.search( query, null, LARQ.NUM_RESULTS );
58  
59              Map1<ScoreDoc, HitLARQ> converter = new Map1<ScoreDoc, HitLARQ>() {
60                  @Override
61                  public HitLARQ map1( ScoreDoc object ) {
62                      return new HitLARQ( s, object );
63                  }
64              };
65              Iterator<ScoreDoc> iterScoreDoc = Arrays.asList( topDocs.scoreDocs ).iterator();
66              Iterator<HitLARQ> iter = new Map1Iterator<>( converter, iterScoreDoc );
67  
68              return iter;
69          } catch ( Exception e ) {
70              throw new ARQLuceneException( "Error during search for '" + queryString + ";", e );
71          }
72      }
73  
74      private synchronized IndexSearcher getIndexSearcher() throws IOException {
75          if ( !reader.isCurrent() ) {
76              // this is the problematic line ... multireader cannot be reopened; was IndexReader newReader =
77              // IndexReader.openIfChanged(reader, true) ;
78  
79              IndexReader newReader = IndexReader.openIfChanged( reader );
80              if ( newReader != null ) {
81                  reader.close();
82                  reader = newReader;
83                  searcher = new IndexSearcher( reader );
84              }
85          }
86  
87          return searcher;
88      }
89  
90  }