`
ssxxjjii
  • 浏览: 938657 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

基于Solr的空间搜索(3)

    博客分类:
  • IM
 
阅读更多

http://ju.outofmemory.cn/entry/711

本文将继续介绍基于Solr的地理位置搜索的第二种实现方案

CartesianTiers+GeoHash

从基于Solr的地理位置搜索(2)文章中可以看到完全基于GeoHash的查询过滤,将完全遍历整个docment文档,从效率上来看并不太合适,所以结合笛卡尔层后,能有效缩减少过滤范围,从性能上能很大程度的提高。

构建索引阶段:

String geoHash = GeoHashUtils.encode(latitude, longitude);
      docment.addField(“geohash”, geoHash);
      //Cartesian Tiers
      int tier = START_TIER;//开始构建索引的层数
      //Create a bunch of tiers, each deeper level has more precision
//将一条记录的经纬度对应全部笛卡尔层的tierBoxId作为域值构建索引
      for (CartesianTierPlotter plotter : plotters) {
        docment.addField(“tier_” + tier , plotter.getTierBoxId(latitude, longitude));
        tier++;
      }

看到这里大家肯定明白了。越相近的经纬度在同层肯定会在同一个网格中,所以他们存储的tierBoxId就会是一样。那么查询的时候通过经纬度对应 层的tierBoxId,也就能找到相同层域的docId,但是如果给定的的查询范围大,可能需要将若干层的所属网格的docId都查到。

   整个查询过程是先通过笛卡尔层将若干个网格涉及的DocList存入bitSet,如下代码所示:

public DocIdSet getDocIdSet(final IndexReader reader) throws IOException {
    final FixedBitSet bits = new FixedBitSet(reader.maxDoc());
final TermDocs termDocs = reader.termDocs();
//需要查询的若干层网格的boxIdList,当然至此已经过滤掉不需要查询层的boxIdList
    final List<Double> area = shape.getArea();
    int sz = area.size();
    final Term term = new Term(fieldName);//
    // iterate through each boxid
    for (int i =0; i< sz; i++) {
      double boxId = area.get(i).doubleValue();
termDocs.seek(term.createTerm(NumericUtils.doubleToPrefixCoded(boxId)));
      // iterate through all documents
      // which have this boxId
//遍历所有包含给定boxId的docList,并将其放入bitset
      while (termDocs.next()) {
        bits.set(termDocs.doc());
      }
    }
    return bits;
  }

介绍完笛卡尔层的计算后,接下来介绍笛卡尔层过滤后返还的bitset如何和geoHash结合,从实现上讲其实很简单,就是将通过笛卡尔层过滤的 数据结果集合 依次遍历计算其与查询给定的经纬度坐标的球面距离,同时将该计算距离和查询指定范围距离进行比较,如果大于给定距离,则将当前记录继续过滤掉,那么最终剩 下的数据结果集合,将是满足查询条件的地理位置结果集合。具体实现流程见如下代码:

//将笛卡尔层的Filter作为Geohash的Filter参数传递进去,形成一个过滤链
 filter = distanceFilter = new GeoHashDistanceFilter(cartesianFilter, lat, lng, miles, geoHashFieldPrefix);

再看GeoHashDistanceFilter中最核心的方法getDocIdSet():

 public DocIdSet getDocIdSet(IndexReader reader) throws IOException {
      //在这里使用到了Lucene的FieldCache来作为缓存,实际上缓存了一个以docId为下标,base32编码为值的数组
    final String[] geoHashValues = FieldCache.DEFAULT.getStrings(reader, geoHashField);
    final int docBase = nextDocBase;
    nextDocBase += reader.maxDoc();
    return new FilteredDocIdSet(startingFilter.getDocIdSet(reader)) {
      @Override
      public boolean match(int doc) {
        //通过笛卡尔层的过滤后的doc直接找到对应的base32编码
        String geoHash = geoHashValues[doc];
        //通过解码将base32还原成经纬度坐标
        double[] coords = GeoHashUtils.decode(geoHash);
        double x = coords[0];
        double y = coords[1];
        Double cachedDistance = distanceLookupCache.get(geoHash);
        double d;
        if (cachedDistance != null) {
          d = cachedDistance.doubleValue();
        } else {
           //计算2个经纬度坐标的距离
          d = DistanceUtils.getDistanceMi(lat, lng, x, y);
          distanceLookupCache.put(geoHash, d);
        }
       //小于给定查询距离的的docid放入缓存,以供下次使用,同时返回True代表当前docId是满足条件的记录
        if (d < distance){
          distances.put(doc+docBase, d);
          return true;
        } else {
          return false;
        }
      }
    };

  从上述分析中大家应该可以想到 采用笛卡尔层 Filter结合GoHash Filter的实现方案,在计算规模上会比单独使用GeoHash少了很多,而在查询性能也会有更优异的表现。

最后附上一个本地Demo的查询实例,用geofilter查找给定经纬度500km内的数据:

q=*:*&fq={!geofilt pt=30.15,-79.85 sfield=tier d=500}

查询返回结果:

分享到:
评论

相关推荐

    基于java-solr-geo空间坐标搜索、距离排序、分页

    基于solr-geo空间搜索 1、Solr的schema.xml配置 定义坐标field 2、Solr的data-config.xml配置 建立索引 3、java查询语法 坐标距离、分页、排序

    基于Solr与Oracle的农村土地承包经营权确权成果空间数据库设计与实现.pdf

    3. **ArcEngine开发的数据库管理系统**:基于ArcEngine,开发了一个数据库管理系统,ArcEngine是一款强大的GIS开发平台,能帮助构建地理信息系统应用。这个系统验证了数据库设计的可行性,并通过实际功能应用实验,...

    solr4.9.0.zip

    10. **地理空间搜索**:Solr支持地理空间搜索,可以基于地理位置进行范围查询和距离排序。 11. **XML/JSON API**:Solr 提供了基于HTTP的XML和JSON接口,方便与其他应用程序集成。 12. **强大的文档处理**:Solr...

    ikanalyzer-solr中文分词包兼容solr7.5

    ikanalyzer-solr中文分词包是专门为Apache Solr设计的一款强大的中文分词工具,它在处理中文文本时能够有效地进行词语切分,提高搜索准确性和效率。标题中提到的"ikanalyzer-solr中文分词包兼容solr7.5"意味着这个...

    Apache Solr(solr-7.7.3.tgz)

    5. **contrib**: 这里包含了各种社区贡献的模块,提供了额外的功能,如CSV导入、数据驱动的文档更新、地理空间搜索等。 6. **docs**: 包含Solr的API参考文档和其他技术文档,对于开发者和管理员来说非常有用。 7. ...

    solr开发维护参考

    Solr是Apache软件基金会的一个开源项目,它是基于Java的全文搜索服务器,主要功能包括文档索引、搜索、排序和分布式处理。Solr利用了Lucene库的强大搜索功能,并且提供了更高级别的API和服务,使得企业级搜索应用的...

    SOLR的学习资料

    3. **分布式搜索**:SOLR云(SolrCloud)提供了分布式部署和自动复制,以实现高可用性和水平扩展。 4. **实时搜索**:SOLR的实时索引功能允许在不重启服务的情况下更新索引,提高用户体验。 5. **优化索引**:定期...

    solr-4.10.3

    5. **地理位置搜索**:内置对地理空间数据的支持,可以基于地理位置进行搜索和排序。 6. **XML/JSON等多格式支持**:Solr支持多种数据交换格式,如XML、JSON和CSV,便于与各种应用程序集成。 7. **自定义插件**:...

    lucene4 solr4j arIk4

    为此,开源社区提供了强大的全文搜索引擎框架——Lucene4,以及与其紧密集成的Java客户端库Solr4J,以及在地理空间搜索领域颇具影响力的AriK4。本文将深入探讨这三个技术的核心概念、使用方法以及它们在实际应用中的...

    solr集群搭建

    Apache Solr是一款基于Lucene的开源全文搜索引擎,它提供了分布式搜索、近实时处理、多字段排序等功能。以下是对Solr集群搭建的详细步骤和关键知识点的解释。 1. **系统需求**:首先,确保你的系统满足Solr的硬件和...

    solr压缩包

    它基于Java平台,是Lucene库的一个强大封装,提供了丰富的查询接口和配置选项,使得企业能够快速构建起自己的搜索应用。在描述中提到的"solr需要的下载",意味着这个压缩包可能是Solr的安装包或者更新版本。 在...

    solr 7 官方文档

    Solr基于Java开发,能够处理大量的索引和查询请求,并提供了丰富的功能来满足各种搜索需求。 1. **Solr核心概念** - **索引**:Solr通过建立索引来实现快速搜索。索引是预处理的数据结构,用于存储和检索信息。 -...

    Apache Solr 架设搜索服务器 学习笔记

    5. **地理空间搜索**:支持地理位置的索引和查询,可用于地图应用等场景。 ### 五、Solr 的管理工具 1. **Solr Admin UI**:Web 基于的管理界面,可以查看 Core 状态、管理索引、执行查询等操作。 2. **solr-cli**...

    Solr搜索引擎部署应用.docx

    Solr搜索引擎是一款基于Apache Lucene的开源全文检索服务器,广泛应用于大数据环境中的高效检索和数据分析。本篇文档主要介绍了如何在Windows环境下部署Solr,并进行数据导入和搜索查询。 首先,部署Solr需要准备的...

    一键安装伪分布式zk集群-solr集群脚本

    Zookeeper是一个分布式协调服务,而Solr是基于Lucene的全文搜索引擎,它们在大数据和分布式计算领域广泛应用。 Zookeeper是Apache Hadoop项目的一部分,主要用于管理分布式应用的数据,提供诸如配置管理、命名服务...

    最新版windos solr-8.11.0.zip

    6. **数据分析**:Solr内建了丰富的数据分析组件,如Faceting(分面导航)用于分类和统计,Highlighting(高亮显示)用于查询结果的突出显示,以及Spatial Search(空间搜索)支持地理位置的搜索。 7. **优化与性能...

    Solr 学习笔记(五)-Solr扩展之分布式索引实例

    SolrCloud是Solr的一个分布式管理模式,它基于Zookeeper进行集群管理和协调。在SolrCloud中,文档被分片并分布在多个Solr节点上,确保了数据的冗余和容错性。每个分片都是一个完整的Solr索引,可以独立工作,这样就...

    solr7.5官方文档doc加pdf格式

    8. **地理位置搜索**:内置对地理空间数据的支持,可以基于经纬度执行范围和距离查询。 9. **处理大量数据**:Solr设计用于处理PB级别的数据,可以有效地处理大规模的搜索需求。 10. **API支持**:提供了丰富的API...

    solr4.5版本

    - **地理空间搜索**:支持基于地理位置的搜索,对地理坐标进行索引和查询。 2. **SolrCloud**: - **分布式搜索**:Solr 4.5引入了SolrCloud模式,允许在分布式环境中部署和管理Solr,实现了数据的自动分片、复制...

    solr4.10.3.rar

    3. ** faceted search(分面搜索)**:Solr提供了分面搜索功能,用户可以根据不同的属性进行筛选,这在电子商务网站中非常常见,如按价格、品牌或评价等进行筛选。 4. **实时索引**:Solr具有实时索引的能力,一旦...

Global site tag (gtag.js) - Google Analytics