1.索引库的维护
索引库删除
(1) 全删除
第一步:先对文档进行分析
public IndexWriter getIndexWriter() throws Exception { // 第一步:创建java工程,并导入jar包 // 第二步:创建一个indexwriter对象(创建索引) // 1.指定索引库的存放位置Directory对象 Directory directory = FSDirectory.open(Paths.get("E:\\temp\\index")); //文件系统目录 file system directory // Directory directory2 = new RAMDirectory(); // 2.指定一个分析器,对文档内容进行分析 Analyzer analyzer = new StandardAnalyzer();//官方推荐分词器 IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer); IndexWriter indexWriter = new IndexWriter(directory, indexWriterConfig); return indexWriter; }
第二步:直接调用IndexWriter的deleteAll方法
@Test public void testAllDelete() throws Exception { IndexWriter indexWriter = getIndexWriter(); indexWriter.deleteAll(); indexWriter.close(); }
(2) 根据条件删除
第一步:与上面代码一样
第二步:使用IndexWriter的deleteDocuments方法,传入query条件
@Test public void testDelete() throws Exception { IndexWriter indexWriter = getIndexWriter(); Query query = new TermQuery(new Term("fileName", "apache")); indexWriter.deleteDocuments(query); indexWriter.close(); }
索引库修改
对索引库的修改,其实就是先删除,在添加。
第一步:同上
第二步:调用IndexWriter的updateDocument方法
//修改 @Test public void testUpdate() throws Exception { IndexWriter indexWriter = getIndexWriter(); Document doc = new Document(); doc.add(new TextField("fileN", "测试文件名", Store.YES)); doc.add(new TextField("fileC", "测试文件内容", Store.YES)); indexWriter.updateDocument(new Term("fileName", "spring"), doc); indexWriter.close(); }
索引库查询所有
(1) 使用query的子类查询 (用对象查)
(1.1) MatchAllDocsQuery
//IndexReader IndexSearcher public IndexSearcher getIndexSearcher() throws Exception { // 第一步:创建一个Directory对象,也就是索引库存放的位置 Directory directory = FSDirectory.open(Paths.get("E:\\temp\\index")); // 第二步:创建一个indexReader对象,需要指定Directory对象 IndexReader indexReader =DirectoryReader.open(directory); // 第三步:创建一个indexsearcher对象,需要指定IndexReader对象 IndexSearcher indexSearcher = new IndexSearcher(indexReader); return indexSearcher; } //执行查询结果 public void printResult(IndexSearcher indexSearcher, Query query) throws Exception { // 第五步:执行查询。 TopDocs topDocs = indexSearcher.search(query, 10); // 第六步:返回查询结果,遍历查询结果并输出 ScoreDoc[] scoreDocs = topDocs.scoreDocs; for (ScoreDoc scoreDoc : scoreDocs) { int doc = scoreDoc.doc; Document document = indexSearcher.doc(doc); //文件名称 String fileName = document.get("fileName"); System.out.println(fileName); //文件内容 String fileContent = document.get("fileContent"); System.out.println(fileContent); //文件路径 String fileSize = document.get("fileSize"); System.out.println(fileSize); //文件大小 String filePath = document.get("filePath"); System.out.println(filePath); System.out.println("---------"); } } //查询所有 @Test public void testMatchAllDocsQuery() throws Exception { IndexSearcher indexSearcher = getIndexSearcher(); Query query = new MatchAllDocsQuery(); printResult(indexSearcher, query); //关闭资源 indexSearcher.getIndexReader().close(); }
(1.2) TermQuery 精准查询,之前已经说过。
(1.3) 根据数值范围查询 (注意:数值范围是否包括边界,使用的方法不一样).
//根据数值范围查询 /* 版本更新说明: 在lucene4.10中,关于数字范围的查询是使用的NumericRangerQuery 使用方式: Query query = NumericRangerQuery.newFloatRange(域名,较小值,较大值,是否包含较小值,是否包含较大值) 在lucene6.6中(不知最早在什么版本,没有细查),NumericRangerQuery被legacyNumericRangerQuery替代 在lucene7中(应该是从7开始的),lucene开始使用PointValue来替代之前的Filed.而数字范围查询方法也进行了修改, Float/Long/IntPoint.newRangeQuery取代了之前的NumericRangeQuery的newFloat/Long/IntRange 使用方法: Query query = Float.newRangeQuery(域名,较小值,较大值); 而这种查询方法默认包含范围的端点值,即查询的是 较小值<=域名<=较大值 如果不想包含端点值: 1.不包含左端点值(即较小值):Query query = Float.newRangeQuery(域名,FloatPoint.nextUp(较小值),较大值); 2.不包含右端点值(即较大值):Query query = Float.newRangeQuery(域名,较小值,Float.nextDown(较大值)); 3.均不包含:结合1和2即可 */ @Test public void testNumericRangeQuery() throws Exception { IndexSearcher indexSearcher = getIndexSearcher(); Query query = LongPoint.newRangeQuery("fileSize", 47L, 200L); printResult(indexSearcher, query); //关闭资源 indexSearcher.getIndexReader().close(); }
(1.3) 组合查询条件
//可以组合查询条件 /* 1、MUST和MUST表示“与”的关系,即“交集”。 2、MUST和MUST_NOT前者包含后者不包含。 3、MUST_NOT和MUST_NOT没意义 4、SHOULD与MUST表示MUST,SHOULD失去意义; 5、SHOUlD与MUST_NOT相当于MUST与MUST_NOT。 6、SHOULD与SHOULD表示“或”的概念。 版本更新说明: 在lucene 4.10.3中,组合查询还有无参构造方法,可以通过下面这种方式实现组合查询: Query query = new BooleanQuery() //添加查询条件,并指定该条件的判断级别 query.add(query1,Occur.MUST); query.add(query2,Occur.MUST); 在lucene7.1中,组合查询只有一个有参构造方法,并没有无参构造方法.而是多了一个静态内部类Builder public static class Builder { private int minimumNumberShouldMatch; private final List<BooleanClause> clauses = new ArrayList<>(); //大概是4.10.3中的BooleanQuery的无参构造 public Builder() {} //设置最小需要匹配的数 public Builder setMinimumNumberShouldMatch(int min) { this.minimumNumberShouldMatch = min; return this; } public Builder add(BooleanClause clause) { if (clauses.size() >= maxClauseCount) { throw new TooManyClauses(); } clauses.add(clause); return this; } //4.10.3中的BooleanQuery的add方法,支持链式编程(一般使用这个add方法) public Builder add(Query query, Occur occur) { return add(new BooleanClause(query, occur)); } //返回一个BooleanQuery,用于构造Query public BooleanQuery build() { return new BooleanQuery(minimumNumberShouldMatch, clauses.toArray(new BooleanClause[0])); } } 7.1中,Occur.MUST等全都放到了BooleanClause中,所以,Occur.MUST等变成了BooleanClause.Occur.MUST等 所以在lucene中,组合查询的使用方法: Query booleanQuery = new BooleanQuery.Builder().add(query1,BooleanClause.Occur.MUST).add(query2,Boolean.Occur.MUST).build(); */ public void testBooleanQuery() throws Exception { IndexSearcher indexSearcher = getIndexSearcher(); Query query1 = new TermQuery(new Term("fileName","lucene")); Query query2 = new TermQuery(new Term("fileName","springmvc")); //Occur有MUST, SHOULD, MUST_NOT, FILTER BooleanQuery booleanQuery = new BooleanQuery.Builder().add(query1, Occur.MUST).add(query2, Occur.SHOULD).build(); printResult(indexSearcher, booleanQuery); //关闭资源 indexSearcher.getIndexReader().close(); }
(2) 使用queryparser查询 (用语法查)
(2.1) 基础的语法查询,关键词查询:
域名 + ":" + 搜索的关键字
//条件解析的对象查询 @Test public void testQueryParser() throws Exception { IndexSearcher indexSearcher = getIndexSearcher(); //参数1,默认查询的域 QueryParser queryParser = new QueryParser("fileName", new IKAnalyzer()); // "*:*" : 表示查询所有 "域:值" Query query = queryParser.parse("springcloud is springmvc"); printResult(indexSearcher, query); }
(2.2) 范围查询
域名 + " :" + [最小值 TO 最大值]
例如:size:[1 TO 100]
范围查询在lucene中支持数值类型,不支持字符串类型。在solr中支持字符串类型。
(2.3) 组合条件查询
(2.3.1) +条件1+条件2:两个条件之间是并且的关系 and
例如:+fileName:apache + content:apache
(2.3.2) +条件1 条件2 :必须满足第一个条件,应该满足第二个条件
例如:+filename:apache content:apache
(2.3.3)条件1 条件2:两个条件满足其一即可
例如:filename:apache content:apache
(2.3.4) -条件1 条件2:必须不满足条件1,要满足条件2
例如:-filename:apache content:apache
(3) 多个默认检索 MultiFieldQueryParser
//条件解析对象查询 多个默认域 @Test public void testMultiFieldQueryParser() throws Exception { IndexSearcher indexSearcher = getIndexSearcher(); //参数1,多个默认查询的域 String[] fields = {"fileName", "fileContent"}; //参数2,采用分词器 MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields, new IKAnalyzer()); // "*:*" : 表示查询所有 "域:值" Query query = queryParser.parse("apache is lucene"); printResult(indexSearcher, query); }