lucene&solr全文检索_5索引的维护

增加新内容的时候,或者删除的时候我们需要对索引进行增删改查来进行索引的维护。

先上代码:

 
package come.me.lucene;
//索引维护
import java.io.File;
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field.Store;
import org.apache.lucene.document.TextField;
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.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.queryparser.classic.QueryParser;
import org.apache.lucene.queryparser.flexible.standard.nodes.NumericRangeQueryNode;
import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.MatchAllDocsQuery;
import org.apache.lucene.search.NumericRangeQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.TermQuery;
import org.apache.lucene.search.TopDocs;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;
import org.junit.jupiter.api.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;

public class LuceneManager {
    public IndexWriter getIndexWriter() throws Exception{
        Directory directory =FSDirectory.open(new File("D:\\temp\\index"));//创建document对象
        Analyzer analyzer=new StandardAnalyzer();//官方推荐标准分析器
        IndexWriterConfig config=new IndexWriterConfig(Version.LUCENE_4_10_3, analyzer);//第一个变量为用的lucene版本号,第二个为分析器对象
        return new IndexWriter(directory,config);
        
    }
    
    @Test
    public void addDocument() throws Exception {
        //索引库存放路径
        Directory directory = FSDirectory.open(new File("D:\\temp\\0108\\index"));
        
        IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, new IKAnalyzer());
        //创建一个indexwriter对象
        IndexWriter indexWriter = new IndexWriter(directory, config);
        //创建一个Document对象
        Document document = new Document();
        //向document对象中添加域。
        //不同的document可以有不同的域,同一个document可以有相同的域。
        document.add(new TextField("filename", "新添加的文档", Store.YES));
        document.add(new TextField("content", "新添加的文档的内容", Store.NO));
        document.add(new TextField("content", "新添加的文档的内容第二个content", Store.YES));
        document.add(new TextField("content1", "新添加的文档的内容要能看到", Store.YES));
        //添加文档到索引库
        indexWriter.addDocument(document);
        //关闭indexwriter
        indexWriter.close();
        
    }
    
    
    //索引全部删除
    @Test
    void testDeleteAll() throws Exception {
        IndexWriter indexwriter =getIndexWriter();
        indexwriter.deleteAll();
        indexwriter.close();
    }
    //根据条件删除
    @Test
    void testDelete() throws Exception {
        IndexWriter indexwriter =getIndexWriter();
        Query query=new TermQuery(new Term("fileName","apache"));
        indexwriter.deleteDocuments(query);
        indexwriter.close();
    }
    //修改索引
    @Test
    void testUpdate() throws Exception {
        IndexWriter indexwriter =getIndexWriter();
        Document doc=new Document();
        doc.add(new TextField("fileN","jsjs",Store.YES));
        //先删除lucene再加上doc的内容
        indexwriter.updateDocument(new Term("fileName","lucene"),doc,new IKAnalyzer());
    }
    
    public IndexSearcher getIndexSearcher() throws Exception{
//        第一步:创建一个Directory对象,也就是索引库存放的位置。
        Directory directory =FSDirectory.open(new File("D:\\temp\\index"));
//        第二步:创建一个indexReader对象,需要指定Directory对象。
        IndexReader indexreader=DirectoryReader.open(directory);
//        第三步:创建一个indexsearcher对象,需要指定IndexReader对象
        return new IndexSearcher(indexreader);
    }
    
    public void print(IndexSearcher indexSearcher,Query query) throws Exception {
        TopDocs topDocs = indexSearcher.search(query,20);
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : scoreDocs) {
            int doc = scoreDoc.doc;
            Document doc2 = indexSearcher.doc(doc);
            //文件名称
            System.out.println("文件名称");
            String fileName=doc2.get("fileName");
            System.out.println(fileName);
            //文件内容
            System.out.println("文件内容");
            String fileContent=doc2.get("fileContent");
            System.out.println(fileContent);
            //文件路径
            System.out.println("文件路径");
            String filePath=doc2.get("filePath");
            System.out.println(filePath);
            //文件大小
            System.out.println("文件大小");
            String fileSize=doc2.get("fileSize");
            System.out.println(fileSize);
            System.out.println("-------------------");
        }
    }
    
    //查询所有
    @Test
    void testMatchAllDocsQuery() throws Exception {
        IndexSearcher indexSearcher = getIndexSearcher();
        Query query=new MatchAllDocsQuery();
        print(indexSearcher,query);
        //关闭资源
        indexSearcher.getIndexReader().close();
    }
    
    //按数值范围查找
    @Test
    void testNumericRangeQuery() throws Exception {
        IndexSearcher indexSearcher = getIndexSearcher();
        Query query = NumericRangeQuery.newLongRange("size", 1l, 1000l, true, true);
        print(indexSearcher,query);
        //关闭资源
        indexSearcher.getIndexReader().close();
    }
    
    //组合查询
    @Test
    void testBooleanQuery() throws Exception {
        IndexSearcher indexSearcher = getIndexSearcher();
        BooleanQuery booleanqurey =new BooleanQuery();
        Query q1=new TermQuery(new Term("fileName","apache"));
        Query q2=new TermQuery(new Term("fileName","lucene"));
        booleanqurey.add(q1, Occur.MUST);//must对应and,must not 对应not,should对应or
        booleanqurey.add(q2, Occur.SHOULD);//本例子为必须有q1但是有没有q2都可以
        //关闭资源
        indexSearcher.getIndexReader().close();
    }
    
    //条件解析的对象查询
    @Test
    void testQueryParser() throws Exception {
        IndexSearcher indexSearcher = getIndexSearcher();
        QueryParser queryparser =new QueryParser("fileName",new IKAnalyzer());//第一个参数为默认查询的域名
        Query query = queryparser.parse("fileContent:lucene");//如果在此输入的域名与默认域名冲突,则默认域名会失效,如果搜索的内容为一段话则会被分析器分析之后再查询,例如what is your 则包含what或者your的都要
        print(indexSearcher, query);
        //关闭资源
        indexSearcher.getIndexReader().close();
    }
    
    //多个默认域查询
    @Test
    void testMultiFieldQueryParser() throws Exception {
        IndexSearcher indexSearcher = getIndexSearcher();
        String[] fields= {"fileName","fileContent"};
        MultiFieldQueryParser MFqueryparser =new MultiFieldQueryParser(fields,new IKAnalyzer());//第一个参数为数组名
        Query query = MFqueryparser.parse("lucene");
        print(indexSearcher, query);
        //关闭资源
        indexSearcher.getIndexReader().close();
    }
}

    1.索引的添加  

      步骤:

      向索引库中添加document对象。

      第一步:先创建一个indexwriter对象

      第二步:创建一个document对象

      第三步:把document对象写入索引库

      第四步:关闭indexwriter

    2.索引的删除

      (1:删除全部

       (2:根据条件删除

    3.索引的修改

    4.索引的查询:

    

      对要搜索的信息创建Query查询对象,Lucene会根据Query查询对象生成最终的查询语法,类似关系数据库Sql语法一样Lucene也有自己的查询语法,比如:“name:lucene”表示查询Fieldname为“lucene”的文档信息。

 

    1)查询所有

    2)精准查询已经在上个博客中介绍

    3)数值范围查询

    4)组合条件查询

    5)用于语法查询

    6)多个默认域查询

 

注意:可在每个方法中输出query来查看查询的语法:

 

1、基础的查询语法,关键词查询:

域名+“:”+搜索的关键字

例如:content:java

2、范围查询

域名+:+[最小值 TO 最大值]

例如:size:[1 TO 1000]

范围查询在lucene中支持数值类型,不支持字符串类型。在solr中支持字符串类型。

3、组合条件查询

1+条件1 +条件2:两个条件之间是并且的关系and

例如:+filename:apache +content:apache

2)+条件1 条件2:必须满足第一个条件,应该满足第二个条件

例如:+filename:apache content:apache

3)条件1 条件2:两个条件满足其一即可。

例如:filename:apache content:apache

4-条件1 条件2:必须不满足条件1,要满足条件2

例如:-filename:apache content:apache

Occur.MUST 查询条件必须满足,相当于and

+(加号)

Occur.SHOULD 查询条件可选,相当于or

 

空(不用符号)

Occur.MUST_NOT 查询条件不能满足,相当于not非

-(减号)

 

第二种写法:

条件1 AND 条件2

条件1 OR 条件2

条件1 NOT 条件2

 

你可能感兴趣的:(lucene&solr全文检索_5索引的维护)