`
lvyanglin
  • 浏览: 86063 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

lucene分组查询中问题总结

阅读更多

最近需求中需要使用lucene的分组查询,现有API使用GroupingSearch查询,代码如下:
	GroupingSearch groupingSearch = new GroupingSearch("compId");
		groupingSearch.setGroupSort(new Sort(SortField.FIELD_SCORE));
		groupingSearch.setFillSortFields(true);
		//groupingSearch.setCachingInMB(8.0, true);
		groupingSearch.setAllGroups(true);
		// groupingSearch.setAllGroupHeads(true);
		groupingSearch.setGroupDocsLimit(10);

		IndexWriterConfig config = new IndexWriterConfig(new IKAnalyzer());
		config.setOpenMode(OpenMode.CREATE_OR_APPEND);

		LogByteSizeMergePolicy mergePolicy = new LogByteSizeMergePolicy();
		Directory directory = NIOFSDirectory.open(new File("/Users/lvyanglin/searchdata/search/offlineindex").toPath()); // 新建的文件在子目录
		mergePolicy.setMergeFactor(5);
		config.setMergePolicy(mergePolicy);
		config.setSimilarity(new ClassicSimilarity());
		IndexWriter indexWriter = new IndexWriter(directory, config);
		IndexReader reader = DirectoryReader.open(indexWriter);

		
		
		IndexSearcher isearcher = new IndexSearcher(reader);
		Query query = new TermQuery(new Term("id", "20755185"));
		
	

		TopGroups<BytesRef> result = groupingSearch.search(isearcher, query, 0, 1000);

		System.out.println("搜索命中数:" + result.totalHitCount);
		System.out.println("搜索结果分组数:" + result.groups.length);

		Document document;
		for (GroupDocs<BytesRef> groupDocs : result.groups) {
			System.out.println("分组:" + groupDocs.groupValue.utf8ToString());
			System.out.println("组内记录:" + groupDocs.totalHits);

			// System.out.println("groupDocs.scoreDocs.length:" +
			// groupDocs.scoreDocs.length);
			for (ScoreDoc scoreDoc : groupDocs.scoreDocs) {
				System.out.println("compId="+isearcher.doc(scoreDoc.doc).get("compId"));
			}
		}

	}


但是不管怎么调试都会出现:

Exception in thread "main" java.lang.IllegalStateException: unexpected docvalues type NONE for field 'compId' (expected=SORTED). Re-index with correct docvalues type.
	at org.apache.lucene.index.DocValues.checkField(DocValues.java:212)
	at org.apache.lucene.index.DocValues.getSorted(DocValues.java:264)
	at org.apache.lucene.search.grouping.term.TermFirstPassGroupingCollector.doSetNextReader(TermFirstPassGroupingCollector.java:91)
	at org.apache.lucene.search.SimpleCollector.getLeafCollector(SimpleCollector.java:33)
	at org.apache.lucene.search.MultiCollector.getLeafCollector(MultiCollector.java:121)
	at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:660)
	at org.apache.lucene.search.IndexSearcher.search(IndexSearcher.java:473)
	at org.apache.lucene.search.grouping.GroupingSearch.groupByFieldOrFunction(GroupingSearch.java:193)
	at org.apache.lucene.search.grouping.GroupingSearch.search(GroupingSearch.java:129)
	at com.shunteng.service.test.v3.GroupSearchTest2.main(GroupSearchTest2.java:79)



问题在于分组排序字段必须为SortedDocValuesField,因为是long类型字段所以我就使用SortedNumbericDocValuesField这个字段建索引,运行后还是发生以上错误。百度基本上找个不到问题原因,官网也是没什么解释,官网wiki上也没有例子。只能debug代码来找出问题,看是在那个环节出现的异常。直接抛出异常的方法是DocValues.java中checkField方法,

private static void checkField(LeafReader in, String field, DocValuesType... expected) {
    FieldInfo fi = in.getFieldInfos().fieldInfo(field);
    if (fi != null) {
      DocValuesType actual = fi.getDocValuesType();
      throw new IllegalStateException("unexpected docvalues type " + actual + 
                                        " for field '" + field + "' " +
                                        (expected.length == 1 
                                        ? "(expected=" + expected[0]
                                        : "(expected one of " + Arrays.toString(expected)) + "). " +
                                        "Re-index with correct docvalues type.");
    }
  }

看下面方法进入此方法抛出异常,制药进入上面这个方法必定抛出异常。所以要找出为什么进入这个方法:

 public static SortedDocValues getSorted(LeafReader reader, String field) throws IOException {
    SortedDocValues dv = reader.getSortedDocValues(field);
    if (dv == null) {
      checkField(reader, field, DocValuesType.SORTED);
      return emptySorted();
    } else {
      return dv;
    }
  }



上面这个方法getSorted是关键条件,深入=reader.getSortedDocValues(field);这个方法如下


 @Override
   @Override
  public final SortedDocValues getSortedDocValues(String field) throws IOException {
    ensureOpen();
    Map<String,Object> dvFields = docValuesLocal.get();
    
    Object previous = dvFields.get(field);
    if (previous != null && previous instanceof SortedDocValues) {
      return (SortedDocValues) previous;
    } else {
      FieldInfo fi = getDVField(field, DocValuesType.SORTED);
      if (fi == null) {
        return null;
      }
      SortedDocValues dv = getDocValuesReader().getSorted(fi);
      dvFields.put(field, dv);
      return dv;
    }
  } 


这个previous instanceof SortedDocValues 如果成立 或这个后面类型为SortedDocValuesField 就不会有下面return null,问题就是在于我们配置索引分组字段的时候必须要使用SortedDocValuesField 这个类型的字段。不能使用SortedNumbericDocValuesField,来建索引,这个也是lucene奇葩地方。
我写这个文章目的是总结最近起找问题的心得,在使用阿里巴巴dubbo的时候也遇到到处找不到资料的情况,我们需要一步一步的debug出来问题根源比baidu上更靠谱速度也许更快。


分享到:
评论

相关推荐

    lucene分组查询优化facet

    一、Lucene分组查询原理 Lucene的分组查询(Faceting)是通过对索引中的文档进行多级分类来实现的。它首先会计算每个分面值的文档频率,然后对匹配查询条件的文档进行分组计数。这个过程涉及到倒排索引的遍历和统计...

    Lucene全文搜索 分组,精确查找,模糊查找

    一、Lucene分组查询 在数据检索中,分组查询常常用于对结果进行分类展示,帮助用户更清晰地理解搜索结果的分布。Lucene通过`FieldCache`和`Grouping` API来实现这一功能。首先,我们需要在索引时为需要分组的字段...

    lucene-grouping-3.5.0.jar分组统计+分类统计插件

    lucene-grouping-3.5.0.jar分组统计+分类统计插件 分组统计+分类统计

    Lucene的简单介绍

    5. 默认实现了一套强大的查询引擎:Lucene的查询引擎默认实现了布尔操作、模糊查询(FuzzySearch)、分组查询等多种功能,用户无需编写代码即可获得强大的查询能力。 Lucene在搜索过程中,首先需要建立索引。索引...

    Lucene in Action英文版

    - **调试工具**:提供工具帮助开发者调试索引和查询问题。 - **社区贡献**:参与社区活动,贡献代码或文档,促进Lucene的发展。 #### 八、Lucene的移植与集成 - **跨平台支持**:由于Lucene被移植到了多种编程语言...

    lucene5.X与lucene3.60的版本差异

    4. Lucene-5127:删除了`IndexWriterConfig`中的`setTermIndexInterval`、`setReaderTermsIndexDivisor`和`TermsIndexDivisor`,以减少内存使用。术语索引间隔的配置应直接传递给编解码器,或者针对每个字段进行设置...

    Java全文检索引擎Lucene的应用.pdf

    5. **预置的查询引擎**:Lucene默认提供了一套强大的查询引擎,包括布尔操作、模糊查询、分组查询等功能,大大减轻了开发者的负担。 #### 四、Lucene的运行机制 Lucene的核心功能主要包括两个方面:建立索引库和...

    lucene,solr的使用

    4. **查询处理**:用户提交查询请求时,Solr会解析请求中的参数,并利用已有的索引快速返回结果。 5. **结果排序与过滤**:根据用户的需求对检索结果进行排序、分组等操作。 6. **返回结果**:将最终的检索结果以...

    Lucene5.2.1jar

    总结,Lucene 5.2.1版本提供了完整的全文检索解决方案,包括高效的索引构建、灵活的查询语法、强大的搜索功能以及丰富的扩展特性。无论是小型应用还是大规模企业级系统,Lucene都能满足开发者对高效全文搜索的需求。...

    整理Lucene.net一些简单属性说明

    总结来说,Lucene.net提供了一个强大且灵活的框架,用于构建高性能的全文搜索引擎。通过理解并熟练运用上述的属性和组件,开发者可以创建出满足各种需求的搜索解决方案。在实际应用中,根据具体场景选择合适的...

    lucene7.1.0所需jar包

    4. **文档和字段**: `lucene-docvalues.jar`和`lucene-grouping.jar`分别处理文档值和文档分组,这对于根据特定字段对搜索结果进行排序或分组非常有用。 5. **高性能特性**: `lucene-highlighter.jar`提供了高亮...

    Lucene in Action 2nd Edition MEAP Jun 2010

    - **查询类型**:详细说明了Lucene支持的各种查询类型,如布尔查询(Boolean Query)、短语查询(Phrase Query)等,并探讨了如何根据用户输入创建这些查询。 - **人类可读性**:讨论了如何使查询更易于理解和编写,以及...

    es的简单查询和聚合查询用法说明

    聚合查询(Aggregations)是ES中的统计分析工具,用于对数据进行汇总和分组,有助于我们获取更深入的洞察。 1. **术语聚合(Term Aggregation)**:按指定字段的唯一值进行分组,计算每组的数量。例如,统计某个...

    Solr调研总结

    Solr还提供了灵活的XML配置,支持Lucene查询语言的扩展,如结果分组、过滤和高亮显示,以及一个全面的HTML管理界面和日志监控功能。 Solr与Lucene的关系并非替代,而是互补。Lucene是一个全文检索库,专注于搜索...

    java使用es查询的示例代码

    Java 使用 ES 查询的示例代码 Java 是当前最流行的编程语言之一,而 Elasticsearch(简称 ES)是当前流行的企业...在 Java 中使用 ES 可以解决查询速度不够快、效率不够高的问题,使用 ES 工具类可以轻松地进行查询。

    solr各个热点功能详解

    开发者可以将Lucene集成到自己的应用程序中,为文本数据建立索引。Lucene的流行在于其灵活性,可以处理各种文本格式的文档。 3. Solr与Lucene的区别 Solr是对Lucene的封装和扩展,提供了一个完整的搜索服务器解决...

    HBase应用实践专场HBaseforSolr.pdf

    - **分组查询**:对于数据的分组统计等操作,HBase同样存在局限性。 - **分词检索**:对于文本数据的检索,需要进行分词处理,这也是HBase所欠缺的能力之一。 ### 解决方案探索 为了解决上述问题,通常会采用以下...

    solr 企业搜索引擎教程

    ### Apache Solr 企业搜索引擎教程知识点总结 #### 1. Apache Solr 概述 - **Solr**:Apache Solr 是一款高度可扩展且高性能的企业级搜索平台,由Apache软件基金会维护。它是一个开源搜索服务器,使用Java语言编写...

    solr4二次开发文档

    Solr 是 Lucene 的一个面向企业级搜索的封装和扩展,它提供了搜索服务器的完整功能,包括动态字段、唯一键、查询语言扩展、结果分组过滤、文本分析、缓存策略、管理界面、日志监控以及增量更新和快照发布等。...

Global site tag (gtag.js) - Google Analytics