lucene一个TermFilter的简单实现

public abstract DocsEnum docs(Bits liveDocs, DocsEnum reuse, int flags) throws IOException;

经过一天的研究,总算有些进展. 希望大家提出各种意见,欢迎拍砖!  lucene版本:4.3.1

小插曲,原本想写写spetial search,但是研究研究着,就了解到了termFilter. 因此,见到代码后,不要奇怪啊.有机会的话,再写一些关于spetial的实现.虽然有现成的实现,可是,依然想弄明白,具体是怎么回事. 欢迎大家拍一些有深度的砖.

你可以拍砖,但是你拍得一定要有意义~

核心类:

package com.pptv.search.list.index.increment;

import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Iterator;

import org.apache.commons.lang.NumberUtils;
import org.apache.lucene.index.AtomicReader;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.index.Fields;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.Terms;
import org.apache.lucene.index.TermsEnum;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Filter;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.FixedBitSet;

public class MyOwnFilter extends Filter {

	public static void main(String[] args) throws Exception {
		SpatialSearchTest.main(args);
	}

	@Override
	public DocIdSet getDocIdSet(AtomicReaderContext context, Bits acceptDocs)
			throws IOException {
		// lazy init if needed - no need to create a big bitset ahead of time
		System.out.println(">>>> MyOwnFilter in");
		final AtomicReader reader = context.reader();
		// A. 生成一个结果集合,并初始化到最大
		FixedBitSet result = new FixedBitSet(reader.maxDoc());
		// B. 通过得到所有的 词元
		final Fields fields = reader.fields();
		// 显示fields
		showFields(fields);
		// terms操作
		String termName = "able";
		Terms terms = fields.terms(termName);
		System.out.println(termName + "_" + "terms.size() = " + terms.size());
		// C. 得到具体的每一个词元
		TermsEnum reuse = null;
		reuse = terms.iterator(reuse);

		for (int i = 0; i < terms.size(); i++) {
			reuse.next();
			System.out.println("----" + i + "----" + reuse.term());
			System.out.println("内容:"
					+ new String(reuse.term().bytes, 0, reuse.term().length,
							Charset.forName("UTF-8")));
			// BytesRef text = new BytesRef("2".getBytes());
			// D. 查看所有terms中,是否存在此term
			// System.out.println(reuse.seekExact(text, false));
			// System.out.println(text);

			// E. 通过词元,对倒排词典进行反查
			DocsEnum docs = null;
			// no freq ,since we don't need them
			docs = reuse.docs(acceptDocs, docs, DocsEnum.FLAG_NONE);

			while (docs.nextDoc() != DocIdSetIterator.NO_MORE_DOCS) {
				int docId = docs.docID();
				System.out.println("collected:" + docId);
				result.set(docId);
			}

		}

		System.out.println("<<<< MyOwnFilter out");
		return result;
	}

	private void showFields(final Fields fields) {
		System.out.println("fields.size() = " + fields.size());
		Iterator<String> ite = fields.iterator();
		int i = 0;
		while (ite.hasNext()) {
			++i;
			System.out.println("\t" + i + ":" + ite.next());
		}
	}

}

入口类:

package com.pptv.search.list.index.increment;

import java.io.IOException;
import java.util.BitSet;
import java.util.Set;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.DoubleDocValuesField;
import org.apache.lucene.document.DoubleField;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.FieldType;
import org.apache.lucene.document.NumericDocValuesField;
import org.apache.lucene.document.StringField;
import org.apache.lucene.index.AtomicReader;
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.ComplexExplanation;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.Filter;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.Weight;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
import org.apache.lucene.util.DocIdBitSet;
import org.apache.lucene.util.NumericUtils;
import org.apache.lucene.util.OpenBitSetIterator;
import org.apache.lucene.util.ToStringUtils;
import org.apache.lucene.util.Version;

@SuppressWarnings("unused")
public class SpatialSearchTest {
	static Version version = Version.LUCENE_43;

	public static void main(String[] args) throws Exception {
		RAMDirectory d = new RAMDirectory();
		IndexWriter writer = new IndexWriter(d, new IndexWriterConfig(version,
				new StandardAnalyzer(version)));
		doIndex(writer);

		IndexSearcher searcher = new IndexSearcher(DirectoryReader.open(d));
		System.out.println("maxDoc:" + searcher.getIndexReader().maxDoc());
		// Query,Filter
		Query query = new MyQuery();
		query.setBoost(1.0001f);
		System.out.println("query:" + query);
		Filter filter = null;
		filter = createFilter();
		System.out.println("filter:" + filter);

		TopDocs tds = searcher.search(query, filter, 10);
		for (int i = 0; i < tds.scoreDocs.length; i++) {
			ScoreDoc sd = tds.scoreDocs[i];
			Document doc = searcher.doc(sd.doc);
			pintDoc(doc);
		}
	}

	private static Filter createFilter() {
		Filter filter;
		// filter = new MyFilter(new Term("able", "1"));
		filter = new MyOwnFilter();
		return filter;
	}

	private static void pintDoc(Document doc) {
		String lat = doc.get("lat");
		String lng = doc.get("lng");
		System.out.println("(" + lng + "," + lat + ")");
	}

	private static void doIndex(IndexWriter writer) throws Exception,
			IOException {
		for (int i = 0; i < 100 && i < 5; i++) {
			Document document = new Document();
			indexLocation(document, 100l + i, (Math.random() * 100l) + i * i,
					i % 2 == 0 ? "0" : "abcd你好");
			writer.addDocument(document);
		}

		writer.forceMerge(1);
		writer.close();
	}

	private static void indexLocation(Document document, double longitude,
			double latitude, String able) throws Exception {
		DoubleField lat = new DoubleField("lat", latitude, Store.YES);
		DoubleField lng = new DoubleField("lng", longitude, Store.YES);
		document.add(new StringField("able", able, Store.YES));
		document.add(lat);
		document.add(lng);
	}
}

实际上就是通过Filter暴露给我们的下面这个方法

public abstract DocIdSet getDocIdSet(AtomicReaderContext context, Bits acceptDocs) throws IOException;

通过context得到reader,再得到fields,再得到terms,最后通过

public abstract DocsEnum docs(Bits liveDocs, DocsEnum reuse, int flags) throws IOException;

方法,将结果合并封装,并返回.注意,这个过程是在搜索过程中,执行的.

下面这句话,希望高手们拍下砖,

目前,我猜想lucene是先query,后filter的?对吗?  怎么都感觉不对.希望明示,改天有机会,再来验证这个问题.

时间: 2024-10-13 01:34:19

lucene一个TermFilter的简单实现的相关文章

每天一个设计模式-1 简单工厂

每天一个设计模式-1  简单工厂 1.简单工厂的定义 提供一个创建对象实例的功能,而无须关心其具体实现(核心). 虽然不能让模块外部知道模块内部的具体实现,但模块内部是可以知道具体实现类的.干脆在模块内部建一个类,用这个类来创建接口,然后把创建号的接口返回给客户端:这样,外部应用就只需要根据这个类来获取相应的接口对象,通过这个接口对象就可以操作接口定义的方法了.显然,这个类就像一个工厂,专门用来生成(生产)需要的接口对象. 2.简单的例子 说明: 代码: Api:接口,wear是一个公有方法.

提示13. 附加一个实体的简单方式

提示13. 附加一个实体的简单方式 问题: 在早先的一些提示中,我们讨论了使用Attach来加载一个处于未改变(unchanged)状态的东西到ObjectContext从而避免进行查询的开销. 如果性能是你的目标,Attach就是要选择的武器. 不幸的是我们的API不能适应99%的情况,即每个类型仅有一个实体集(entity set)的情况.Entity Framework支持单类型多实体集(Multiple Entity Sets perType)或称MEST,且API反映了这一点,要求你提

【美妙的Python之中的一个】Python简单介绍及环境搭建

美妙的Python之Python简单介绍及安装         简而言之: Python 是能你无限惊喜的语言,与众不同.             1.Python:          Python英文意思为蟒蛇,故又称为蟒蛇语言,在图标设计上有所体现,贵铎·范·罗萨姆(Guido van Rossum)于1989年创立.Python的特质,简单,优雅,健壮,继承传统编程语言的强大性与通用性,同一时候兼具简单脚本的简单性.         Python的哲学:仅仅用一种方法,最好是仅仅有一种方法

写了一个Java的简单缓存模型

缓存操作接口 /** * 缓存操作接口 * * @author xiudong * * @param <T> */ public interface Cache<T> { /** * 刷新缓存数据 * * @param key 缓存key * @param target 新数据 */ void refresh(String key, T target); /** * 获取缓存 * * @param key 缓存key * @return 缓存数据 */ T getCache(Str

一个Nodejs的简单计算测试程序

测试目的: 1 测试二维数组的使用 2 输出函数的使用 代码: var util = require('util'); a = 3; b = 4; c = a + b; a = []; for(i = 0; i < 10; i++) { info = ""; for(j = 0; j < 10; j++) { a[i,j] = i + j; util.print(util.format('%d', a[i, j])); util.print(' '); } console.

感觉Java写一个窗口真心简单,很易上手

上学期学习了Java ,感觉Java写一个窗口真心简单,很易上手,也就难怪很多开发人员选择Java作为自己的开发编程语言.但是由于自身对windows的热爱,让我觉得c.c++语言才是我亲睐的编程语言,虽然难度大些,但是这才能体现能力所在.其实之前一直想自学一下win32,但是由于时间的显示和种种原因而耽搁了,于是今年暑假决心深入学习win32. 在学习过程中呢,我会在此留下自己的学习心得,当做自己的笔记.初学者可以借鉴,高手可以多多指教,呵呵…… 好了,今天开始做第一课的笔记吧: 学习Win3

写一个php memcache 简单的函数

在一个项目中添加了memcache层,但由于数据库本来压力就不大,数据量很小,所以性能改善不是特别明显,因此学习并应用下来记录一下方便以后自己使用.这里我只应用了直接调用对应api函数的方法,另外一种方法是创建对象来连接memcache,具体是$mem=new Memcache,然后再调用对象里的方法来操作要存储的item. 本次使用环境为php 5.4.17, yum安装的驱动: php-pecl-memcache-3.0.8-1.el5.remi 代码如下: $MEMCACHE["host&

一个linux下简单的纯C++实现Http请求类(GET,POST,上传,下载)

目录 一个linux下简单的纯C++实现Http请求类(GET,POST,上传,下载) Http协议简述 HttpRequest类设计 请求部分 接收部分 关于上传和下载 Cpp实现 关于源码中的Logger 使用示例 一个linux下简单的纯C++实现Http请求类(GET,POST,上传,下载) 最近写了点关于Http上传下载文件相关的,于是今天整理下代码. Http协议简述 HttpRequest类设计 使用示例 Http协议简述 协议:网络协议的简称,网络协议是通信计算机双方必须共同遵从

[Lucene]-Lucene基本概述以及简单实例

一.Lucene基本介绍: 基本信息:Lucene 是 Apache 软件基金会的一个开放源代码的全文检索引擎工具包,是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎.Lucene 的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎. 文件结构:自上而下树形展开,一对多. 索引Index:相当于库或者表. 段Segment:相当于分库或者分表. 文档Document:相当一条数据 ,如小说吞噬