• lucene&solr学习——索引维护


    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);
            
        }
  • 相关阅读:
    每日总结2021.9.14
    jar包下载mvn
    每日总结EL表达语言 JSTL标签
    每日学习总结之数据中台概述
    Server Tomcat v9.0 Server at localhost failed to start
    Server Tomcat v9.0 Server at localhost failed to start(2)
    链表 java
    MVC 中用JS跳转窗体Window.Location.href
    Oracle 关键字
    MVC 配置路由 反复走控制其中的action (int?)
  • 原文地址:https://www.cnblogs.com/FanJava/p/10394231.html
Copyright © 2020-2023  润新知