首页 > 学院 > 开发设计 > 正文

Lucene索引库查询(五)

2019-11-06 07:14:22
字体:
来源:转载
供稿:网友

一、索引库的查询

对要搜索的信息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库Sql语法一样。Lucene也有自己的查询语法,比如:“name:lucene”表示查询Field的name为“lucene”的文档信息。可通过两种方法创建查询对象:(1)使用Lucene提供Query子类Query是一个抽象类,lucene提供了很多查询对象,比如TermQuery项精确查询,NumericRangeQuery数字范围查询等。如下代码:
Query query = new TermQuery(new Term("name", "lucene"));(2) 使用QueryParse解析查询表达式QueryParse会将用户输入的查询表达式解析成Query对象实例。如下代码:
QueryParser queryParser = new QueryParser("name", new IKAnalyzer());Query query = queryParser.parse("name:lucene");

二、使用query的子类查询

2.1 TermQueryTermQuery,通过项查询,TermQuery不使用分析器,所以建议匹配不分词的Field域查询,比如订单号、分类ID号等。根据词进行搜索(只能从文本中进行搜索)。指定要查询的域和要查询的关键词:
@Test	public void termQueryTest() throws Exception{		Term term = new Term("fileName","lucene");		TermQuery termQuery = new TermQuery(term); 		Directory dir = createDirectory();		IndexReader indexReader = createIndexReader(dir);		IndexSearcher indexSearcher = createIndexSearcher(indexReader);		TopDocs topdocs = indexSearcher.search(termQuery, 2);		System.out.PRintln("=====count=====" + topdocs.totalHits);		ScoreDoc[] scoreDocs = topdocs.scoreDocs;		for(ScoreDoc scoreDoc : scoreDocs){			int docID = scoreDoc.doc;			Document document = indexReader.document(docID);			System.out.println("fileName:" + document.get("fileName"));			System.out.println("fileSize:" + document.get("fileSize"));			System.out.println("fileContext:" + document.get("fileContext"));			System.out.println("============================================================");		}	}2.2 NumericRangeQuery可以根据数值范围查询。
/**	 * 根据数字范围查询	 * 查询文件大小 大于100小于10000的文章	 */	@Test	public void numericRangeQueryTest() throws Exception{		//查询文件大小 大于100小于10000的文章		//第一次参数:域名		//第二个参数:最小值		//第三个参数:最大值		//第四个参数:是否包含最小值		//第五个参数:是否包含最大值		Query query = NumericRangeQuery.newLongRange("fileSize", 100L, 10000L, true, true);		Directory dir = createDirectory();		IndexReader indexReader = createIndexReader(dir);		IndexSearcher indexSearcher = createIndexSearcher(indexReader);		TopDocs topdocs = indexSearcher.search(query, 2);		System.out.println("=====count=====" + topdocs.totalHits);		ScoreDoc[] scoreDocs = topdocs.scoreDocs;		for(ScoreDoc scoreDoc : scoreDocs){			int docID = scoreDoc.doc;			Document document = indexReader.document(docID);			System.out.println("fileName:" + document.get("fileName"));			System.out.println("fileSize:" + document.get("fileSize"));			System.out.println("fileContext:" + document.get("fileContext"));			System.out.println("============================================================");		}	}2.3 BooleanQuery可以组合查询条件。
@Test	public void booleanQueryTest() throws Exception{				Query numericRangeQuery = NumericRangeQuery.newLongRange("fileSize", 100L, 10000L, true, true);				Term term = new Term("fileName","lucene");		TermQuery termQuery = new TermQuery(term); 				//booleanQuery,可以根据多个条件组合进行查询		//例如:文件名称包含lucene的,并且文件大小 大于100小于10000的文章		BooleanQuery booleanQuery = new BooleanQuery();				//Occur是逻辑关键词		//MUST:相当于and		//MUST_NOT:相当于not		//SHOULD:相当于or		//注意:单独使用MUST_NOT没有任何意义		booleanQuery.add(numericRangeQuery, Occur.MUST);		booleanQuery.add(termQuery, Occur.MUST);				Directory dir = createDirectory();		IndexReader indexReader = createIndexReader(dir);		IndexSearcher indexSearcher = createIndexSearcher(indexReader);		TopDocs topdocs = indexSearcher.search(booleanQuery, 2);		System.out.println("=====count=====" + topdocs.totalHits);		ScoreDoc[] scoreDocs = topdocs.scoreDocs;		for(ScoreDoc scoreDoc : scoreDocs){			int docID = scoreDoc.doc;			Document document = indexReader.document(docID);			System.out.println("fileName:" + document.get("fileName"));			System.out.println("fileSize:" + document.get("fileSize"));			System.out.println("fileContext:" + document.get("fileContext"));			System.out.println("============================================================");		}	}2.4 MatchAllDocsQuery使用MatchAllDocsQuery查询索引目录中的所有文档。
/**	 * 查询所有文档	 */	@Test	public void matchAllDocsQueryTest() throws Exception{		MatchAllDocsQuery matchAllDocsQuery = new MatchAllDocsQuery();				Directory dir = createDirectory();		IndexReader indexReader = createIndexReader(dir);		IndexSearcher indexSearcher = createIndexSearcher(indexReader);		TopDocs topdocs = indexSearcher.search(matchAllDocsQuery, 2);		System.out.println("=====count=====" + topdocs.totalHits);		ScoreDoc[] scoreDocs = topdocs.scoreDocs;		for(ScoreDoc scoreDoc : scoreDocs){			int docID = scoreDoc.doc;			Document document = indexReader.document(docID);			System.out.println("fileName:" + document.get("fileName"));			System.out.println("fileSize:" + document.get("fileSize"));			System.out.println("fileContext:" + document.get("fileContext"));			System.out.println("============================================================");		}	}

三、使用queryparser查询

通过QueryParser也可以创建Query,QueryParser提供一个Parse方法,此方法可以直接根据查询语法来查询。Query对象执行的查询语法可通过System.out.println(query);查询。需要使用到分析器。建议创建索引时使用的分析器和查询索引时使用的分析器要一致。根据域名进行搜索,可以设置默认搜索域,推荐使用. (只能从文本中进行搜索)。3.1 QueryParser需要加入queryParser依赖的jar包。
@Test	public void QueryParserTest() throws Exception{		Analyzer analyzer = createAnalyzer();		QueryParser queryParser = new QueryParser("fileContext", analyzer);		Query query = queryParser.parse("fileContext:recommended");		Directory dir = createDirectory();		IndexReader indexReader = createIndexReader(dir);		IndexSearcher indexSearcher = createIndexSearcher(indexReader);		TopDocs topdocs = indexSearcher.search(query, 2);		System.out.println("=====count=====" + topdocs.totalHits);		ScoreDoc[] scoreDocs = topdocs.scoreDocs;		for(ScoreDoc scoreDoc : scoreDocs){			int docID = scoreDoc.doc;			Document document = indexReader.document(docID);			System.out.println("fileName:" + document.get("fileName"));			System.out.println("fileSize:" + document.get("fileSize"));			System.out.println("fileContext:" + document.get("fileContext"));			System.out.println("============================================================");		}	}3.2 MulitFieldQueryParser可以指定多个默认搜索域。
/**	 * 从文件名称和文件内容这2个域中查询,只要含有lucene的就被查询出来	 * @throws Exception	 */	@Test	public void mulitFieldQueryParserTest() throws Exception{		String[] fieldArray = {"fileName","fileContext"};		Analyzer analyzer = createAnalyzer();		MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(fieldArray,analyzer);		Query query = multiFieldQueryParser.parse("lucene");				Directory dir = createDirectory();		IndexReader indexReader = createIndexReader(dir);		IndexSearcher indexSearcher = createIndexSearcher(indexReader);		TopDocs topdocs = indexSearcher.search(query, 2);		System.out.println("=====count=====" + topdocs.totalHits);		ScoreDoc[] scoreDocs = topdocs.scoreDocs;		for(ScoreDoc scoreDoc : scoreDocs){			int docID = scoreDoc.doc;			Document document = indexReader.document(docID);			System.out.println("fileName:" + document.get("fileName"));			System.out.println("fileSize:" + document.get("fileSize"));			System.out.println("fileContext:" + document.get("fileContext"));			System.out.println("============================================================");		}	}

四、公用部分

public  IndexSearcher createIndexSearcher(IndexReader indexReader) {		IndexSearcher indexSearcher = new IndexSearcher(indexReader);		return indexSearcher;	}		public  Analyzer createAnalyzer(){		Analyzer analyzer = new StandardAnalyzer();		return analyzer;	}		public  Directory createDirectory() throws Exception{		Directory directory = FSDirectory.open(new File(indexPath));		return directory;	}		public IndexReader createIndexReader(Directory dir) throws Exception{		@SuppressWarnings("deprecation")		IndexReader indexReader = IndexReader.open(dir);		return indexReader;	}源代码github地址:https://github.com/lucene-in-action/lucene-index-search
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表