lucene Direction类 和 term查询

标签: lucene direction term | 发表时间:2014-08-24 10:18 | 作者:hbiao68
出处:http://www.iteye.com

一 、 Directory介绍

1、使用FSDirectory.open(java.io.File)方法,会根据当前的运行环境打开一个最合理的基于File的Directory。

SimpleFSDirectory : 使用RandomAccessFile类访问文件,但是在并发上面效率不是很高

 

NIOFSDirectory : 使用java.nio.FileChannel,能够提高并发访问效率

 

MMapDirectory : 会根据操作系统64bit或者32bit创建合适的directory对象

 

 

2、new RAMDirectory会从内存中打开directory,好处是速度快,缺点是无法持久化

 

二、Term查询

1、编写各种查询类

package com.hb.lucence;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.lucene.analysis.standard.StandardAnalyzer;
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.document.NumericField;
import org.apache.lucene.index.CorruptIndexException;
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.queryParser.QueryParser;
import org.apache.lucene.queryParser.QueryParser.Operator;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.FuzzyQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.PrefixQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TermRangeQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.search.WildcardQuery;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.LockObtainFailedException;
import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.Version;

public class SearchUtil {
	private Directory directory;
	private IndexReader reader;
	private String[] ids = { "1", "2", "3", "4", "5", "6" };
	private String[] emails = { "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]", "[email protected]" };
	private String[] contents = { "welcome to visited the space,I like book", "hello boy, I like pingpeng ball", "my name is cc I like game", "I like football", "I like football and I like basketball too", "I like movie and swim" };
	private String[] names = { "zhangsan", "lisi", "john", "jetty", "mike", "jake" };
	private Map<String, Float> scores = new HashMap<String, Float>();

	public SearchUtil() {
		scores.put("itat.org", 2.0f);
		scores.put("zttc.edu", 1.5f);
		directory = new RAMDirectory();
		this.index();

	}

	public void index() {
		IndexWriter writer = null;
		try {
			writer = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_35, new StandardAnalyzer(Version.LUCENE_35)));
			writer.deleteAll();
			Document doc = null;
			for (int i = 0; i < ids.length; i++) {
				doc = new Document();
				doc.add(new Field("id", ids[i], Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
				doc.add(new Field("email", emails[i], Field.Store.YES, Field.Index.NOT_ANALYZED));
				doc.add(new Field("email", "test" + i + "@test.com", Field.Store.YES, Field.Index.NOT_ANALYZED));
				doc.add(new Field("content", contents[i], Field.Store.NO, Field.Index.ANALYZED));
				doc.add(new Field("name", names[i], Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
				
				String et = emails[i].substring(emails[i].lastIndexOf("@") + 1);
				System.out.println(et);
				if (scores.containsKey(et)) {
					//配置索引的加权值
					doc.setBoost(scores.get(et));
				} else {
					doc.setBoost(0.5f);
				}
				writer.addDocument(doc);
			}
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (LockObtainFailedException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (writer != null)
					writer.close();
			} catch (CorruptIndexException e) {
				e.printStackTrace();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public IndexSearcher getSearcher() {
		try {
			if (reader == null) {
				this.reader = IndexReader.open(directory);
			} else {
				IndexReader tr = IndexReader.openIfChanged(reader);
				if (tr != null) {
					reader.clone();
					reader = tr;
				}
			}
			return new IndexSearcher(reader);
		} catch (CorruptIndexException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}

	public void searchByTerm(String field, String name, int num) {
		try {
			IndexSearcher searcher = this.getSearcher();
			Query query = new TermQuery(new Term(field, name));
			TopDocs tds = searcher.search(query, num);
			System.out.println("一共查询了 :" + tds.totalHits);
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(doc.get("id") + "---->" + doc.get("name") + "[" + doc.get("email") + "]-->" + doc.get("id") + "," + doc.get("attach") + "," + doc.get("date"));
			}
			// 关闭IndexSearcher对象
			searcher.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	public void searchByTermRange(String field, String start, String end, int num) {
		TopDocs tds;
		try {
			IndexSearcher searcher = getSearcher();
			/**
			 * String field, 索引对应的域 String lowerTerm, 起始查询条件 String upperTerm,
			 * boolean includeLower, boo lean includeUpper
			 */
			Query query = new TermRangeQuery(field, start, end, true, true);
			tds = searcher.search(query, num);
			System.out.println("一共查询了:" + tds.totalHits);
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(doc.get("id") + "---->" + doc.get("name") + "[" + doc.get("email") + "]-->" + doc.get("id") + "," + doc.get("attach") + "," + doc.get("date"));
			}
			searcher.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void searchByNumricRange(String field, int start, int end, int num) {
		TopDocs tds;
		try {
			IndexSearcher searcher = this.getSearcher();
			Query query = NumericRangeQuery.newIntRange(field, start, end, true, true);
			tds = searcher.search(query, 10);
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(doc.get("id") + "---->" + doc.get("name") + "[" + doc.get("email") + "]-->" + doc.get("id") + "," + doc.get("attach") + "," + doc.get("date"));
			}
			searcher.close();
		} catch (IOException e) {
		}
	}

	public void searchByPrefix(String field, String value, int num) {
		try {
			IndexSearcher searcher = this.getSearcher();
			Query query = new PrefixQuery(new Term(field, value));
			TopDocs tds = searcher.search(query, num);
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(doc.get("id") + "---->" + doc.get("name") + "[" + doc.get("email") + "]-->" + doc.get("id") + "," + doc.get("attach") + "," + doc.get("date"));
			}
			searcher.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void searchByWildcard(String field, String value, int num) {
		try {
			IndexSearcher searcher = this.getSearcher();
			// 在传入的value中可以使用通配符:?和*,?表示匹配一个字符,*表示匹配任意多个字符
			Query query = new WildcardQuery(new Term(field, value));
			TopDocs tds = searcher.search(query, num);
			System.out.println("一共查询了 : " + tds.totalHits);
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(doc.get("id") + "---->" + doc.get("name") + "[" + doc.get("email") + "]-->" + doc.get("id") + "," + doc.get("attach") + "," + doc.get("date"));
			}
			searcher.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void searchByFuzzy(String field, String value, int num) {
		try {
			IndexSearcher searcher = this.getSearcher();
			// 
			Query query = new FuzzyQuery(new Term(field, value));
			TopDocs tds = searcher.search(query, num);
			System.out.println("一共查询了 : " + tds.totalHits);
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(doc.get("id") + "---->" + doc.get("name") + "[" + doc.get("email") + "]-->" + doc.get("id") + "," + doc.get("attach") + "," + doc.get("date"));
			}
			searcher.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public void searchByBoolean(int num) {
		try {
			IndexSearcher searcher = this.getSearcher();
			BooleanQuery query = new BooleanQuery();
			/*
			 * BooleanQuery可以连接多个子查询 Occur.MUST表示必须出现 Occur.SHOULD表示可以出现
			 * Occur.MUSE_NOT表示不能出现
			 */
			TermQuery termQuery1 = new TermQuery(new Term("name", "zhangsan"));
			query.add(termQuery1, Occur.MUST_NOT);
			TermQuery termQuery2 = new TermQuery(new Term("content", "game"));
			query.add(termQuery2, Occur.SHOULD);
			TopDocs tds = searcher.search(query, num);
			System.out.println("一共查询了:" + tds.totalHits);
			for (ScoreDoc sd : tds.scoreDocs) {
				Document doc = searcher.doc(sd.doc);
				System.out.println(doc.get("id") + "---->" + doc.get("name") + "[" + doc.get("email") + "]-->" + doc.get("id") + "," + doc.get("attach") + "," + doc.get("date"));
			}
			searcher.close();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}
	

}

 

NumericRange :

数字范围查询 。

//是否包含开始,是否包含结束

Query query = NumericRangeQuery.newIntRange (field, start, end, true, true); 

su.searchByNumricRange("attach", 2, 10, 5);

 

PrefixQuery :

通过字符串前缀来查询。

Query query = new PrefixQuery(new Term(field, value));

//查询以sex开头的

su.searchByPrefix("content", "sex", 10);

 

WildcardQuery :

通配符查询。

//在传入的value中可以使用通配符:?和*,?表示匹配一个字符,*表示匹配任意多个字符
Query query = new WildcardQuery(new Term(field, value));

 //匹配@itat.org结尾的所有字符

 su.searchByWildcard("email", "*@itat.org", 10);
 //匹配j开头的有三个字符的name
 su.searchByWildcard("name", "j???", 10);

 

BooleanQuery :

用于表示布尔查询子句关系的类,包括:BooleanClause.Occur.MUST,BooleanClause.Occur.MUST_NOT,BooleanClause.Occur.SHOULD。

必须包含,不能包含,可以包含三种.有以下6种组合 : 
1.MUST和MUST:取得连个查询子句的交集。 
2.MUST和MUST_NOT:表示查询结果中不能包含MUST_NOT所对应的查询子句的检索结果。 
3.SHOULD与MUST_NOT:连用时,功能同MUST和MUST_NOT。
4.SHOULD与MUST连用时,结果为MUST子句的检索结果,但是SHOULD可影响排序。 
5.SHOULD与SHOULD:表示“或”关系,最终检索结果为所有检索子句的并集。 
6.MUST_NOT和MUST_NOT:无意义,检索无结果。

 

BooleanQuery query = new BooleanQuery();
query.add(new TermQuery(new Term("name", "zhangsan")), Occur.MUST);
query.add(new TermQuery(new Term("content", "welcome")), Occur.MUST_NOT);

 

PhraseQuery :

短语查询。

query.add(new Term("content", "pingpeng"));
query.add(new Term("content", "i"));
query.setSlop(3);//要求结果中不仅包含上面的term,并且两个Term之间的间隔不能超过3

 

FuzzyQuery :

模糊查询,在FuzzyQuery类定义中定义了两个成员变量:

private float minimumSimilarity;

private int prefixLength;

minimumSimilarity是最小相似度,取值范围为0.0~1.0,包含0.0但不包含1.0,默认值为0.5。prefixLength是前缀长度,默认为0。

minimumSimilarity表示是最小相似度,可以通过指定一个相似度来决定模糊匹配的严格程度。默认为0.5, 当这个值越小,通过模糊查找出的文档的匹配程度就越低

文档的数量也就越多;当这个值越大,说明要匹配程度更大,匹配的文档数也就越少,当相似度设置为1,那么就退化为TermQuery查询,所以当这个值>=1或<0会抛出IllegalArgumentException异常。

另外一个参数prefixLength表示在进行模糊匹配的时候,要有多少个前缀字母必须完全匹配。 例如当该值设置为“1”,则表示所有此条只有第一个字母与检索关键字相符时,才会被集合选中

 

FuzzyQuery query = new FuzzyQuery(new Term("name", "zhang"), 0.1f, 0);

 

2、使用junit测试各个方法

import java.io.File;
import java.util.Collection;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.FileFileFilter;
import org.apache.lucene.search.NumericRangeQuery;
import org.junit.Test;

import com.hb.lucence.SearchUtil;

public class SearchUtilTest {

	@Test
	public void searchByTermTest(){
		SearchUtil su = new SearchUtil();
		//查询id=1的document
		su.searchByTerm("id", "1", 10);
	}
	
	@Test
	public void searchTermRangeTest(){
		SearchUtil su = new SearchUtil();
		//查询name以a开头和s结尾的
//		su.searchByTermRange("name","a","s",10);
		//由于attachs是数字类型,使用TermRange无法查询
		su.searchByTermRange("id", "2", "4", 10);
	}
	
	@Test
	public void numericRangeQueryTest(){
		SearchUtil su = new SearchUtil();
		//数字查询
		su.searchByNumricRange("attach", 2, 4, 10);
	}
	
	@Test
	public void prefixTest(){
		SearchUtil su = new SearchUtil();
		//查询email域以b开头的
		su.searchByPrefix("email", "b", 10);
	}
	
	@Test
	public void wildcardTest(){
		SearchUtil su = new SearchUtil();
		//查询email字段a开头的所有信息
		su.searchByWildcard("email", "a*", 10);
	}
	
	@Test
	public void fuzzyTest(){
		SearchUtil su = new SearchUtil();
		//查询name字段与jaee相差一个字符的,例如jake
		su.searchByFuzzy("name", "jaee", 10);
	}
	
}

 



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [lucene direction term] 推荐:

lucene Direction类 和 term查询

- - 开源软件 - ITeye博客
一 、 Directory介绍. 1、使用FSDirectory.open(java.io.File)方法,会根据当前的运行环境打开一个最合理的基于File的Directory. SimpleFSDirectory : 使用RandomAccessFile类访问文件,但是在并发上面效率不是很高. NIOFSDirectory : 使用java.nio.FileChannel,能够提高并发访问效率.

elasticsearch 查询(match和term)

- - 企业架构 - ITeye博客
es中的查询请求有两种方式,一种是简易版的查询,另外一种是使用JSON完整的请求体,叫做结构化查询(DSL). 由于DSL查询更为直观也更为简易,所以大都使用这种方式. DSL查询是POST过去一个json,由于post的请求是json格式的,所以存在很多灵活性,也有很多形式. 这里有一个地方注意的是官方文档里面给的例子的json结构只是一部分,并不是可以直接黏贴复制进去使用的.

【国人开发】BBS工具:Miu Term

- wyest - 爱Apps - www.iapps.im
精选限时免费应用,由 AppPusher 为您送达. 无限精彩,尽在 iapps.im. 感谢Sharon在【爱分享】中留言分享. 先来一句题外话:今天开发者老婆过生日,App限免一天哦. iPad版本同期限免,点我下载. 不知道现在还有没有人玩BBS和telnet,今天这款Miu Term便是一个基于 telnet 的上 bbs 软件.

lucene排序

- - 开源软件 - ITeye博客
排序是对于全文检索来言是一个必不可少的功能,在实际运用中,排序功能能在某些时候给我们带来很大的方便,比如在淘宝,京东等一些电商网站我们可能通过排序来快速找到价格最便宜的商品,或者通过排序来找到评论数最高或卖的最好的商品,再比如在Iteye里的博客栏里,每天都会以降序的方式,来显示出最新发出的几篇博客,有了排序,我们就能在某些时候很方便快速的得到某些有效信息,所以说排序功能,无处不在 ^_^.

[原]Lucene系列-facet

- - 文武天下
facet:面、切面、方面. 个人理解就是维度,在满足query的前提下,观察结果在各维度上的分布(一个维度下各子类的数目). 如jd上搜“手机”,得到4009个商品. 其中品牌、网络、价格就是商品的维度(facet),点击某个品牌或者网络,获取更细分的结果. 点击品牌小米,获得小米手机的结果,显示27个.

[原]Lucene系列-FieldCache

- - 文武天下
域缓存,加载所有文档中某个特定域的值到内存,便于随机存取该域值. 当用户需要访问各文档中某个域的值时,IndexSearcher.doc(docId)获得Document的所有域值,但访问速度比较慢,而且只能获得Stored域的值. FieldCache能获得域值数组,根据docId random access域值.

Lucene 使用教程

- - 行业应用 - ITeye博客
1 lucene简介 . 1.1 什么是lucene . Lucene是一个全文搜索框架,而不是应用产品. 因此它并不像 http://www.baidu.com/ 或者google Desktop那么拿来就能用,它只是提供了一种工具让你能实现这些产品. 1.2 lucene能做什么 . 要回答这个问题,先要了解lucene的本质.

Lucene 4.x 之 IndexReader

- - zzm
在Lucene 3.x时代,《Lucene In Action》是一本相当不错的参考书,书中详细介绍了Lucene各种高级使用技术,对于开发者来说非常实用. 但是近期Lucene升级到了4.x版本,在性能等各方面有了很大的提高,值得在新项目中使用. 然而Lucene 4.x中的API相比3.x来说有了很大的改变,《Lucene In Action》中的很多内容都已经过时了,并且由于4.x推出的时间不长,还没有比较好的文档来对用法进行说明,这个系列文章就是想记录下自己使用Lucene 4.x的经验体会,供大家参考使用.

文章: 集成Lucene和HBase

- - InfoQ cn
在所有先进的应用程序中,不管是购物站点还是社交网络乃至风景名胜站点,搜索都扮演着关键的角色. Lucene搜索程序库事实上已经成为实现搜索引擎的标准. 苹果、IBM、Attlassian(Jira)、Wolfram以及很多大家喜欢的公司【1】都使用了这种技术. 因此,大家对任何能够提升Lucene的可伸缩性和性能的实现都很感兴趣.

Solr\Lucene优劣势分析

- - 淘宝网综合业务平台团队博客
最早lucene2.4以及以前,追溯到2008年前后,lucene刚刚引起大家的关注,到后来Nutch. 、solr的出现,lucene变得更加热. Nutch、Solr的发展,极大推动了lucene的升级. 对于一些接触过搜索,使用过lucene、solr的人来说,一般都会感觉lucene、solr很牛逼.