2010-02-05 19 views
0

Quelqu'un a-t-il des expériences en utilisant le composant de recherche spatiale de lucene (lucene 3.0)?Requête lucene simple spatiale ne fonctionne pas?

J'ai essayé un exemple très simple mais n'a pas pu obtenir la recherche de retourner quoi que ce soit, voir ci-dessous pour tous les codes

import java.io.IOException; 

import org.apache.lucene.analysis.WhitespaceAnalyzer; 
import org.apache.lucene.document.Document; 
import org.apache.lucene.document.Field; 
import org.apache.lucene.document.Field.Index; 
import org.apache.lucene.document.Field.Store; 
import org.apache.lucene.index.IndexWriter; 
import org.apache.lucene.index.Term; 
import org.apache.lucene.index.IndexWriter.MaxFieldLength; 
import org.apache.lucene.search.IndexSearcher; 
import org.apache.lucene.search.Query; 
import org.apache.lucene.search.TermQuery; 
import org.apache.lucene.search.TopDocs; 
import org.apache.lucene.spatial.tier.DistanceQueryBuilder; 
import org.apache.lucene.spatial.tier.projections.CartesianTierPlotter; 
import org.apache.lucene.spatial.tier.projections.IProjector; 
import org.apache.lucene.spatial.tier.projections.SinusoidalProjector; 
import org.apache.lucene.store.Directory; 
import org.apache.lucene.store.RAMDirectory; 
import org.apache.lucene.util.NumericUtils; 

public class SpatialLuceneExample{ 
    private static final String LAT_FIELD = "lat", LON_FIELD = "lon", TIER_PREFIX_FIELD = "_localTier"; 

    private double maxMiles = 25, minMiles = 1; // anything lower than 1 mile will just give tier 15 
    // see http://www.nsshutdown.com/projects/lucene/whitepaper/locallucene_v2.html 
    private IProjector projector = new SinusoidalProjector(); 
    private CartesianTierPlotter ctp = new CartesianTierPlotter(0, projector, TIER_PREFIX_FIELD); 
    //startTier is 14 for 25 miles, 15 for 1 miles in lucene 3.0 
    private int startTier = ctp.bestFit(maxMiles), endTier = ctp.bestFit(minMiles);  

    /** 
    * Add the lat, lon, and tier box id to the document 
    * see http://www.nsshutdown.com/projects/lucene/whitepaper/locallucene_v2.html 
    * @param lat 
    * @param lon 
    * @param document a geo document 
    */ 
    private void addSpatialLcnFields(double lat, double lon, Document document){ 
     document.add(new Field(LAT_FIELD, NumericUtils.doubleToPrefixCoded(lat), Field.Store.YES, Field.Index.NOT_ANALYZED)); 
     document.add(new Field(LON_FIELD, NumericUtils.doubleToPrefixCoded(lon), Field.Store.YES, Field.Index.NOT_ANALYZED)); 

     for(int tier = startTier ; tier<= endTier; tier++){ 
      CartesianTierPlotter ctp = new CartesianTierPlotter(tier, projector, TIER_PREFIX_FIELD); 
      double boxId = ctp.getTierBoxId(lat, lon); 
      document.add(new Field(ctp.getTierFieldName(), NumericUtils.doubleToPrefixCoded(boxId), Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS)); 
     } 
    } 


    private void addLocation(IndexWriter writer, String name, double lat, double lon) throws IOException{ 
     Document doc = new Document(); 
     doc.add(new Field("name", name, Field.Store.YES, Index.ANALYZED)); 
     doc.add(new Field("metafile", "doc", Store.YES, Index.ANALYZED)); 
     addSpatialLcnFields(lat, lon, doc); 
     writer.addDocument(doc); 
    } 

    public static void main(String[] args) throws Exception{ 
     SpatialLuceneExample sle = new SpatialLuceneExample(); 
     Directory dir = new RAMDirectory(); 
     IndexWriter writer = new IndexWriter(dir, new WhitespaceAnalyzer(), MaxFieldLength.UNLIMITED); 

     sle.addLocation(writer, "test", 39.9260, -75.1566); 

     writer.commit(); 
     writer.close(); 

     IndexSearcher searcher = new IndexSearcher(dir); 
     DistanceQueryBuilder dq = new DistanceQueryBuilder(39.9260, -75.1566, 10d, LAT_FIELD, LON_FIELD, true); 

     Query tq = new TermQuery(new Term("metafile", "doc")); 
     TopDocs hits = searcher.search(dq.getQuery(tq), 10); 
     for(int i =0; i<hits.totalHits; i++){ 
      Document doc = searcher.doc(hits.scoreDocs[i].doc); 
      System.out.println(doc.get("name")); 
     } 
    } 
} 

Toute aide/commentaires seront grandement appréciés.

Répondre

1

Vous devez ajouter le préfixe de niveau au constructeur de requête:

DistanceQueryBuilder dq = new DistanceQueryBuilder(coord.getLat(), 
      coord.getLon(), miles, Spatial.LAT_FIELD, Spatial.LON_FIELD, 
      Spatial.TIER_PREFIX_FIELD, false);