Lucene(3.5) 的几个查询

4 篇文章 0 订阅

几个查询用法如下代码:

其中

数字范围查询:索引时字段保存为

new NumericField(name,  Field.Store.YES(NO), true(false).setIntValue( num );

Query numericRangeQuery = NumericRangeQuery.newIntRange("size", 20, 150, true, true);

时间范围查询,其实就是数字范围查询, 因为都知道Date是根据一个long 型变量构造出来的

所以用法同上, 只不过需要对传入的日期格式转换成long

文件的内容:
name: java
date:1334494024083
size: 148
content: 全国软件专业人才设计与开发大赛
帽子和服装
Hello
Lucene实战(第二版) Lucene in action
人民邮电出版社
the quick brown fox jumped over the lazy dog



public class QueryTest {
	@Test
	public void testTermQuery() throws Exception {
		// Term t = new Term("content", "服装");
		Term term = new Term("size", "53");
		TermQuery termQuery = new TermQuery(term);
		doSearch(termQuery);
	}

	@Test
	public void testRangeQuery() throws Exception {
		// 通过范围查找, 这里比较的是字符串, 所以实际 20 比 150 大 , 即找不到结果
	//	Query termRangeQuery = new TermRangeQuery("size", "020", "150", true, true);
		//虽然可以通过给20 补0 (即 020)实现20和150的比较, 不过太麻烦, 而且不同的情况补0也不同
		//Lucene 提供了NumberTools.longToString(num), 已过时
		//查看api, NumberTools类已被NumericUtils代替
		//修改如下还是出不来想要的结果, 
		//
	//	Query termRangeQuery = new TermRangeQuery("size", NumericUtils.longToPrefixCoded(20L), NumericUtils.longToPrefixCoded(150L), true, true);
		
		//结果new了半天都没new出来, 继续查api:
		//You create a new NumericRangeQuery with the static factory methods, eg: 
		//Query q = NumericRangeQuery.newFloatRange("weight", 0.03f, 0.10f, true, true);
		//换了半天总与出来了, 原因是建立索引时:使用的Field, 而使用NumericRangeQuery, 必须使用NumericField:
		//api:
		//A Query that matches numeric values within a specified range. To use this,
		//you must first index the numeric values using NumericField (expert: NumericTokenStream).
		//If your terms are instead textual, you should use TermRangeQuery. 
		//NumericRangeFilter is the filter equivalent of this query.
		//numericField有别于Field的几点:
		//NumericField size = new NumericField("size", Field.Store.YES, true);
		//size.setLongValue(file.length());
		Query numericRangeQuery = NumericRangeQuery.newLongRange("size", 20L, 150L, true, true);
		doSearch(numericRangeQuery);
	}

        @Test
        public void testPrefixQuery() throws Exception {
                //Term term = new Term("content", "子");//如果存在“子”开头的分词, 就符合条件查出来了
                Term term = new Term("name", "j");//如果存在“子”开头的分词, 就符合条件查出来了
                PrefixQuery prefixQuery = new PrefixQuery(term);
                doSearch(prefixQuery);
        }
   
        @Test
        public void testBooleanQuery() throws Exception    {
                //query 1
                //查询时间符合以下min_time到max_time区间段的文件
                long min_time = 1334485513724L - 1000L;
                long max_time = 1334485513724L + 1000L;
                Query num_range_query = NumericRangeQuery.newLongRange("date", min_time, max_time, true, true);
        
                //query 2
                Query termQuery = new TermQuery(new Term("name", "test"));//那么重存在test
        
                //query 3
                Query prefixQuery = new PrefixQuery(new Term("name", "j"));
        
                BooleanQuery booleanQuery = new BooleanQuery();
                booleanQuery.add(num_range_query, BooleanClause.Occur.MUST);//查询结果一定要在以上时间范围区间
                booleanQuery.add(termQuery, BooleanClause.Occur.MUST_NOT);//查询结果不能包含name=test的结果
                booleanQuery.add(prefixQuery, BooleanClause.Occur.SHOULD);//可选项
                doSearch(booleanQuery);
        }
	@Test
	public void testPhraseQuery() throws Exception {
		PhraseQuery phraseQuery = new PhraseQuery();
		//为什么就没有add(term) 方法呢?
		//因为Query类里面没有此方法
		//Query phraseQuery = new PhraseQuery(); 
		String[] strs = {"quick", "brown", "jumped", "lazy"};
		//the quick brown fox jumped over the lazy dog
		//quick--1->brown, brown--2->jumped, jumped--3->lazy, 所以slop设成3才会有结果搜到
		//前面的单词要移动slop次到达后面的单词(相邻的单词), 需要注意的是brown-->jumped和 jumped-->brown需要的slop值不同
		//参考《Lucene 实战(第二版)lucene in action》 P92
		phraseQuery.setSlop(3);
		for(String s: strs){
			phraseQuery.add(new Term("content", s));
		}
		doSearch(phraseQuery);
	}
	
	/**
	 * 使用通配符查询, 可能会降低系统性能
	 * @throws Exception
	 */
	@Test
	public void testWildcardQuery() throws Exception {
		//Term term = new Term("name", "ja?a");//? 匹配单个
		Term term = new Term("content", "全*大");//* 匹配所有
		Query wildcardQuery = new WildcardQuery(new Term("name", "j*a"));
		doSearch(wildcardQuery);
	}
	
	/**
	 * 模糊查询
	 * @throws Exception
	 */
	@Test
	public void testFuzzyQuery() throws Exception {
		Term term = new Term("name", "jeav");//通过jeav与实际字段的相似程度查询
		Query fuzzyQuery = new FuzzyQuery(term);
		doSearch(fuzzyQuery);
	}

	private void doSearch(Query query) throws Exception{
		Directory dir = FSDirectory.open(new File("E:/lucene/index"));
		IndexReader reader = IndexReader.open(dir); 
		IndexSearcher searcher = new IndexSearcher(reader);
		TopDocs hits = searcher.search(query, 100);
		System.out.println("共找到" + hits.totalHits + "条记录");
		ScoreDoc[] docs = hits.scoreDocs;
		for(int i = 0; i < docs.length; i++){
			int docId = docs[i].doc;
			Document doc = searcher.doc(docId);
			System.out.println("name: " + doc.get("name"));
			System.out.println("size: " + doc.get("size"));
			System.out.println("content: " + doc.get("content"));
		}
		searcher.close();
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值