lucene的增删改查代码

增删改查

// 创建索引
    @Test
    public void createIndex() throws Exception {

/*
            第一步:创建一个indexwriter对象。
            1)指定索引库的存放位置Directory对象
            2)指定一个分析器,对文档内容进行分析。*/

        // 指定索引库的存放位置Directory对象
        FSDirectory directory = FSDirectory.open(new File("E:\\index"));

        // 索引库还可以存放到内存中
        // Directory directory = new RAMDirectory();

        // 指定一个分析器,对文档内容进行分析
        Analyzer analyzer = new IKAnalyzer();
        // 第一个参数: Lucene的版本信息,可以选择对应的lucene版本也可以使用LATEST
        // 第二个参数:分析器对象
        IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);

        // 创建一个indexwriter对象
        IndexWriter indexWriter = new IndexWriter(directory, config);

        // 要创建索引的文件夹地址
        File f = new File("E:\\searchsource");
        File[] files = f.listFiles();
        for (File file : files) {
            //第二步:创建document对象。
            Document document = new Document();

            // 文件名称
            String fileName = file.getName();
            //第三步:创建field对象,将field添加到document对象中。
            Field fileNameField = new TextField("fileName", fileName, Field.Store.YES);
            // 文件大小
            long fileSize = FileUtils.sizeOf(file);
            Field fileSizeField = new LongField("fileSize", fileSize, Field.Store.YES);
            // 文件路径
            String filePath = file.getPath();
            Field filePathField = new StoredField("filePath", filePath);
            // 文件内容
            String fileContent = FileUtils.readFileToString(file);
            Field fileContentField = new TextField("fileContent", fileContent, Field.Store.YES);

            document.add(fileNameField);
            document.add(fileSizeField);
            document.add(filePathField);
            document.add(fileContentField);

            //第四步:使用indexwriter对象将document对象写入索引库,此过程进行索引创建。并将索引和document对象写入索引库。
            indexWriter.addDocument(document);
        }
        //第五步:关闭IndexWriter对象。
        indexWriter.close();
        System.out.println("lucene创建索引");
    }


    //搜索索引
    @Test
    public void searchIndex() throws Exception {
        //第一步:创建一个Directory对象,也就是索引库存放的位置。(磁盘的位置)
        FSDirectory directory = FSDirectory.open(new File("E:\\index"));

        //第二步:创建一个indexReader对象,需要指定Directory对象。
        IndexReader indexReader = DirectoryReader.open(directory);

        //第三步:创建一个indexsearcher对象,需要指定IndexReader对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        //第四步:创建一个TermQuery对象,指定查询的域和查询的关键词。TermQuery(精准查询)
        Query query = new TermQuery(new Term("fileContent", "北京"));

        //第五步:执行查询。第一个参数是查询对象,第二个参数是查询结果返回的最大值
        TopDocs topDocs = indexSearcher.search(query, 1000);

        //第六步:返回查询结果。遍历查询结果并输出。
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        System.out.println("关键字:[" + "" + "],出现了:" + scoreDocs.length + " 次。");

        for (ScoreDoc scoreDoc : scoreDocs) {
            //scoreDoc.doc属性就是document对象的id
            int doc = scoreDoc.doc;
            Document document = indexSearcher.doc(doc);
            // 文件名称
            String fileName = document.get("fileName");
            System.out.println("名称:" + fileName);
            // 文件内容
            System.out.println("出现的文件内容:");
            String fileContent = document.get("fileContent");
            System.out.println(fileContent);
            // 文件大小
            String fileSize = document.get("fileSize");
            System.out.println("大小:" + fileSize);
            System.out.println("--------------------------------------------------------");
        }
        //第七步:关闭IndexReader对象
        indexReader.close();
    }


    // 1.删除所有
    // 2.删除指定索引
    @Test
    public void deleteIndex() throws Exception {
        FSDirectory directory = FSDirectory.open(new File("E:\\index"));
        Analyzer analyzer = new IKAnalyzer();
        IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
        IndexWriter indexWriter = new IndexWriter(directory, config);

        //1.删除所有
        //indexWriter.deleteAll();
        //indexWriter.close();

        // 2.删除指定索引
        Query query = new TermQuery(new Term("fileContent", "北京"));
        indexWriter.deleteDocuments(query);
        indexWriter.close();
    }

    //修改
    //更新操作: 按照Term进行指定域搜索关键字,如果查到记录就删除,
    //然后将更新后的内容重新生成Document对象
    //如果没有查到记录,则直接将更新后的内容添加一个Document对象
    @Test
    public void updateIndex() throws Exception {
        FSDirectory directory = FSDirectory.open(new File("E:\\index"));
        Analyzer analyzer = new IKAnalyzer();
        IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);
        IndexWriter indexWriter = new IndexWriter(directory, config);

        Document doc = new Document();
        doc.add(new TextField("fileName", "文本", Field.Store.YES));
        doc.add(new LongField("fileSize", 100L, Field.Store.YES));
        doc.add(new StringField("fileContent", "文本", Field.Store.YES));

        indexWriter.updateDocument(new Term("fileContent", "http"), doc, new IKAnalyzer());
        indexWriter.close();
    }

    //query的子类查询
    //(1)查询所有,使用MatchAllDocsQuery查询索引目录中的所有文档
    @Test
    public void searchAll() throws Exception {
        FSDirectory directory = FSDirectory.open(new File("E:\\index"));
        IndexReader indexReader = DirectoryReader.open(directory);
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        //查询所有
        Query query = new MatchAllDocsQuery();
        TopDocs topDocs = indexSearcher.search(query, 20);

        //执行查询结果,遍历查询结果并输出。
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        System.out.println("关键字:[" + "" + "],出现了:" + scoreDocs.length + " 次。");

        for (ScoreDoc scoreDoc : scoreDocs) {
            //scoreDoc.doc属性就是document对象的id
            int doc = scoreDoc.doc;
            Document document = indexSearcher.doc(doc);
            // 文件名称
            String fileName = document.get("fileName");
            System.out.println("名称:" + fileName);
            // 文件内容
            System.out.println("出现的文件内容:");
            String fileContent = document.get("fileContent");
            System.out.println(fileContent);
            // 文件大小
            String fileSize = document.get("fileSize");
            System.out.println("大小:" + fileSize);
            System.out.println("--------------------------------------------------------");
        }
        //关闭IndexReader对象
        indexReader.close();
    }

    //(2)精确查询,TermQuery不使用分析器所以建议匹配不分词的Field域查询,比如订单号、分类ID号等。上述搜索索引时使用的就是这种查询

    //(3)根据数值查询,可以根据数值范围查询。
    @Test
    public void searchByNum() throws Exception {
        FSDirectory directory = FSDirectory.open(new File("E:\\index"));
        IndexReader indexReader = DirectoryReader.open(directory);
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        //NumericRangeQuery可以根据数值范围查询   参数:1.域名 2.最小值 3.最大值 4.是否包含最小值 5.是否包含最大值
        Query query = NumericRangeQuery.newLongRange("fileSize", 1l, 100l, true, true);
        TopDocs topDocs = indexSearcher.search(query, 20);

        //执行查询结果,遍历查询结果并输出。
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        System.out.println("关键字:[" + "" + "],出现了:" + scoreDocs.length + " 次。");

        for (ScoreDoc scoreDoc : scoreDocs) {
            //scoreDoc.doc属性就是document对象的id
            int doc = scoreDoc.doc;
            Document document = indexSearcher.doc(doc);
            // 文件名称
            String fileName = document.get("fileName");
            System.out.println("名称:" + fileName);
            // 文件内容
            System.out.println("出现的文件内容:");
            String fileContent = document.get("fileContent");
            System.out.println(fileContent);
            // 文件大小
            String fileSize = document.get("fileSize");
            System.out.println("大小:" + fileSize);
            System.out.println("--------------------------------------------------------");
        }
        //关闭IndexReader对象
        indexReader.close();
    }

    //(4)组合条件查询,可以组合查询条件
    @Test
    public void BooleanQuery() throws Exception {
        FSDirectory directory = FSDirectory.open(new File("E:\\index"));
        IndexReader indexReader = DirectoryReader.open(directory);
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        //创建一个布尔查询对象
        BooleanQuery query = new BooleanQuery();

        //创建第一个查询条件
        Query query1 = new TermQuery(new Term("fileName", "北京"));
        Query query2 = new TermQuery(new Term("fileContent", "北京"));

        //组合查询条件
        query.add(query1, BooleanClause.Occur.MUST);
        query.add(query2, BooleanClause.Occur.MUST);

        TopDocs topDocs = indexSearcher.search(query, 20);

        //执行查询结果,遍历查询结果并输出。
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        System.out.println("关键字:[" + "" + "],出现了:" + scoreDocs.length + " 次。");

        for (ScoreDoc scoreDoc : scoreDocs) {
            //scoreDoc.doc属性就是document对象的id
            int doc = scoreDoc.doc;
            Document document = indexSearcher.doc(doc);
            // 文件名称
            String fileName = document.get("fileName");
            System.out.println("名称:" + fileName);
            // 文件内容
            System.out.println("出现的文件内容:");
            String fileContent = document.get("fileContent");
            System.out.println(fileContent);
            // 文件大小
            String fileSize = document.get("fileSize");
            System.out.println("大小:" + fileSize);
            System.out.println("--------------------------------------------------------");
        }
        //关闭IndexReader对象
        indexReader.close();
    }

使用queryparser查询

    /*
    * 使用queryparser查询
    *   通过QueryParser也可以创建Query,QueryParser提供一个Parse方法,此方法可以直接根据查询语法来查询。
    *   Query对象执行的查询语法可通过System.out.println(query);查询。
    *   需要使用到分析器。建议创建索引时使用的分析器和查询索引时使用的分析器要一致。
    *   需要加入queryParser依赖的jar包。
    * */
    @Test
    public void QueryParser() throws Exception {
        FSDirectory directory = FSDirectory.open(new File("E:\\index"));
        IndexReader indexReader = DirectoryReader.open(directory);
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        // 创建queryparser对象(第一个参数默认搜索的域,第二个参数就是在查询的时候采用的分析器对象,搜索的值可能是一段话)
        QueryParser queryParser = new QueryParser("fileContent", new IKAnalyzer());

        // *:* =(域:值)  当前的值使用的事默认的域,这里用的是语法
        Query query = queryParser.parse("北京的");
        // 不使用默认的域,也可以自己指定域
        //Query query = queryParser.parse("fileContent:数据");

        TopDocs topDocs = indexSearcher.search(query, 20);

        //执行查询结果,遍历查询结果并输出。
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        System.out.println("关键字:[" + "" + "],出现了:" + scoreDocs.length + " 次。");

        for (ScoreDoc scoreDoc : scoreDocs) {
            //scoreDoc.doc属性就是document对象的id
            int doc = scoreDoc.doc;
            Document document = indexSearcher.doc(doc);
            // 文件名称
            String fileName = document.get("fileName");
            System.out.println("名称:" + fileName);
            // 文件内容
            System.out.println("出现的文件内容:");
            String fileContent = document.get("fileContent");
            System.out.println(fileContent);
            // 文件大小
            String fileSize = document.get("fileSize");
            System.out.println("大小:" + fileSize);
            System.out.println("--------------------------------------------------------");
        }
        //关闭IndexReader对象
        indexReader.close();
    }

在这里插入图片描述

指定多个默认搜索域查询

/*
    * 指定多个默认搜索域:MultiFieldQueryParser
    * */
    @Test
    public void multiFiledQueryParser() throws Exception {
        FSDirectory directory = FSDirectory.open(new File("E:\\index"));
        IndexReader indexReader = DirectoryReader.open(directory);
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);

        //可以指定默认搜索的域是多个
        String[] fields = {"fileName", "fileContent"};

        // 创建queryparser对象(第一个参数默认搜索的域,第二个参数就是在查询的时候采用的分析器对象,搜索的值可能是一段话)
        MultiFieldQueryParser queryParser = new MultiFieldQueryParser(fields, new IKAnalyzer());

        // *:* =(域:值)  当前的值使用的事默认的域,这里用的是语法
        Query query = queryParser.parse("北京 好地方,津京翼都很好");

        TopDocs topDocs = indexSearcher.search(query, 20);

        //执行查询结果,遍历查询结果并输出。
        ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        System.out.println("关键字:[" + "" + "],出现了:" + scoreDocs.length + " 次。");

        for (ScoreDoc scoreDoc : scoreDocs) {
            //scoreDoc.doc属性就是document对象的id
            int doc = scoreDoc.doc;
            Document document = indexSearcher.doc(doc);
            // 文件名称
            String fileName = document.get("fileName");
            System.out.println("名称:" + fileName);
            // 文件内容
            System.out.println("出现的文件内容:");
            String fileContent = document.get("fileContent");
            System.out.println(fileContent);
            // 文件大小
            String fileSize = document.get("fileSize");
            System.out.println("大小:" + fileSize);
            System.out.println("--------------------------------------------------------");
        }
        //关闭IndexReader对象
        indexReader.close();
    }

查看标准分析器的分词效果

    //查看标准分析器的分词效果
    @Test
    public void testTokenStream() throws Exception {
        //创建一个标准分析器对象
        Analyzer analyzer = new IKAnalyzer();
        //获得tokenStream对象,第一个参数:域名,可以随便给一个;第二个参数:要分析的文本内容
        TokenStream tokenStream = analyzer.tokenStream("test", "我爱北京天安门.津京翼是三个地方");
        //添加一个引用,可以获得每个关键词
        CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);
        //添加一个偏移量的引用,记录了关键词的开始位置以及结束位置
        OffsetAttribute offsetAttribute = tokenStream.addAttribute(OffsetAttribute.class);
        //将指针调整到列表的头部
        tokenStream.reset();
        //遍历关键词列表,通过incrementToken方法判断列表是否结束
        while (tokenStream.incrementToken()) {
            //关键词的起始位置
            System.out.println("start->" + offsetAttribute.startOffset());
            //取关键词
            System.out.println(charTermAttribute);
            //结束位置
            System.out.println("end->" + offsetAttribute.endOffset());
        }
        tokenStream.close();
    }

需要的jar!

在这里插入图片描述

配置

ext.dic文件 内容是自己定义扩展的词汇来分词;
stopword.dic文件 内容是自己禁止词汇来分词:
在 IKAnalyzer.cfg.xml 中配置以上两个文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">  
<properties>  
	<comment>IK Analyzer 扩展配置</comment>
	<!--用户可以在这里配置自己的扩展字典 -->
	<entry key="ext_dict">ext.dic;</entry> 
	
	<!--用户可以在这里配置自己的扩展停止词字典-->
	<entry key="ext_stopwords">stopword.dic;</entry> 
	
</properties>

猜你喜欢

转载自blog.csdn.net/qq_45928727/article/details/108519643