开发者

Spatial lucene simple query doesn't work?

开发者 https://www.devze.com 2022-12-19 20:24 出处:网络
does anyone have any experiences using the lucene\'s spatial search component (lucene 3.0)? I tried a very simple example but could not get the search to return anything, see below for all the codes

does anyone have any experiences using the lucene's spatial search component (lucene 3.0)?

I tried a very simple example but could not get the search to return anything, see below for all the 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.ge开发者_Go百科tTierFieldName(), 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"));
        }
    }
}

Any helps/comments will be greatly appreciated.


You need to add the tier prefix to the query builder:

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

精彩评论

暂无评论...
验证码 换一张
取 消