本文是Lucene系列文章中的最后一篇,看完本文后代表Lucene已经入门了,后续学习可以通过官方文档和研读源码进行。建议继续学习笔者后续更新的关于Elasticsearch的文章。本系列教程所有源码可以访问github下载:

本文继续使用此系列文章之前的代码结构和工具类。在正式学习删除索引前请确保学习过我之前的文章,并且使用我之前的文章中的代码构建好项目。如果没有学习过我之前的文章,但是有一定的基础的同学可以直接从本系列第六篇文章开始复制代码构建项目。
首先启动TestLuceneFor14这个类(本系列第六篇文章中有),我们来搜索一下这个关键字。搜索结果如下:

...
索引中,总共要添加 147939 条记录,当前添加进度是: 100% 
请输入查询关键字:鞭
当前关键字是:鞭
找到 5 个命中.
找到 5 个命中.
序号	匹配度得分	结果
1	6.346492	51173	张裕至宝特质三<span style='color:red'>鞭</span>酒200ml六支套装 至宝特质三<span style='color:red'>鞭</span>酒六支套装	食品主会场	158.0	山东烟台	538410222893<br>
2	5.98791	141769	圣喜酱牛<span style='color:red'>鞭</span>男性大爱开袋即食250克山东德州特产新鲜黄牛<span style='color:red'>鞭</span>非耗牛	零食会场	50.0	山东潍坊	45787754358<br>
3	4.6063056	31289	欧舒丹马<span style='color:red'>鞭</span>草清新沐浴露250ml/500ml清爽清凉深层清洁男女	美妆主会场	180.0	浙江杭州	43062612851<br>
4	4.324372	31290	欧舒丹唇膏 马<span style='color:red'>鞭</span>草清新润唇膏保湿滋润补水护唇膏 男女唇部护理	美妆主会场	85.0	浙江杭州	527371320856<br>
5	4.0749598	31291	欧舒丹身体乳 马<span style='color:red'>鞭</span>草润肤露润体乳液250ml柔肤保湿 清爽男士可用	美妆主会场	260.0	浙江杭州	42089347256<br>
请输入查询关键字:

可以看见一个id为51173的记录,如果我们删除该索引,就不会查询到该记录。下面我们使用删除该索引的代码来测试,完整代码:

public class TestLuceneDeleteIndex {

    public static void main(String[] args) throws Exception {
        // 1. 准备中文分词器
        Analyzer analyzer = new SmartChineseAnalyzer();
        // 2. 索引
        Directory index = createIndex(analyzer);

        // 3. 查询器

        Scanner s = new Scanner(System.in);

        //删除id=51173的数据
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        IndexWriter indexWriter = new IndexWriter(index, config);
        indexWriter.deleteDocuments(new Term("id", "51173"));
        indexWriter.commit();
        indexWriter.close();

        while (true) {
            System.out.print("请输入查询关键字:");
            String keyword = s.nextLine();
            System.out.println("当前关键字是:" + keyword);
            Query query = new QueryParser("name", analyzer).parse(keyword);

            // 4. 搜索
            IndexReader reader = DirectoryReader.open(index);
            IndexSearcher searcher = new IndexSearcher(reader);
            int numberPerPage = 10;
            ScoreDoc[] hits = searcher.search(query, numberPerPage).scoreDocs;

            // 5. 显示查询结果
            showSearchResults(searcher, hits, query, analyzer);
            // 6. 关闭查询
            reader.close();
        }

    }

    private static void showSearchResults(IndexSearcher searcher, ScoreDoc[] hits, Query query, Analyzer analyzer) throws Exception {
        System.out.println("找到 " + hits.length + " 个命中.");

        SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");
        Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));

        System.out.println("找到 " + hits.length + " 个命中.");
        System.out.println("序号\t匹配度得分\t结果");
        for (int i = 0; i < hits.length; ++i) {
            ScoreDoc scoreDoc = hits[i];
            int docId = scoreDoc.doc;
            Document d = searcher.doc(docId);
            List<IndexableField> fields = d.getFields();
            System.out.print((i + 1));
            System.out.print("\t" + scoreDoc.score);
            for (IndexableField f : fields) {

                if ("name".equals(f.name())) {
                    TokenStream tokenStream = analyzer.tokenStream(f.name(), new StringReader(d.get(f.name())));
                    String fieldContent = highlighter.getBestFragment(tokenStream, d.get(f.name()));
                    System.out.print("\t" + fieldContent);
                } else {
                    System.out.print("\t" + d.get(f.name()));
                }
            }
            System.out.println("<br>");
        }
    }

    private static Directory createIndex(Analyzer analyzer) throws IOException {
        Directory index = new RAMDirectory();
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        IndexWriter writer = new IndexWriter(index, config);
        String fileName = "140k_products.txt";
        InputStream inputStream = ProductUtil.class.getClassLoader().getResourceAsStream(fileName);
//        InputStream inputStream = ProductUtil.class.getResourceAsStream("/"+fileName);
        List<Product> products = file2list(inputStream);
        int total = products.size();
        int count = 0;
        int per = 0;
        int oldPer = 0;
        for (Product p : products) {
            addDoc(writer, p);
            count++;
            per = count * 100 / total;
            if (per != oldPer) {
                oldPer = per;
                System.out.printf("索引中,总共要添加 %d 条记录,当前添加进度是: %d%% %n", total, per);
            }

        }
        writer.close();
        return index;
    }

    private static void addDoc(IndexWriter w, Product p) throws IOException {
        Document doc = new Document();
        doc.add(new TextField("id", String.valueOf(p.getId()), Field.Store.YES));
        doc.add(new TextField("name", p.getName(), Field.Store.YES));
        doc.add(new TextField("category", p.getCategory(), Field.Store.YES));
        doc.add(new TextField("price", String.valueOf(p.getPrice()), Field.Store.YES));
        doc.add(new TextField("place", p.getPlace(), Field.Store.YES));
        doc.add(new TextField("code", p.getCode(), Field.Store.YES));
        w.addDocument(doc);
    }
}

搜索结果:

索引中,总共要添加 147939 条记录,当前添加进度是: 100% 
请输入查询关键字:鞭
当前关键字是:鞭
找到 4 个命中.
找到 4 个命中.
序号	匹配度得分	结果
1	5.98791	141769	圣喜酱牛<span style='color:red'>鞭</span>男性大爱开袋即食250克山东德州特产新鲜黄牛<span style='color:red'>鞭</span>非耗牛	零食会场	50.0	山东潍坊	45787754358<br>
2	4.6063056	31289	欧舒丹马<span style='color:red'>鞭</span>草清新沐浴露250ml/500ml清爽清凉深层清洁男女	美妆主会场	180.0	浙江杭州	43062612851<br>
3	4.324372	31290	欧舒丹唇膏 马<span style='color:red'>鞭</span>草清新润唇膏保湿滋润补水护唇膏 男女唇部护理	美妆主会场	85.0	浙江杭州	527371320856<br>
4	4.0749598	31291	欧舒丹身体乳 马<span style='color:red'>鞭</span>草润肤露润体乳液250ml柔肤保湿 清爽男士可用	美妆主会场	260.0	浙江杭州	42089347256<br>
请输入查询关键字:

51173的记录已经搜索不到了,说明我们已经成功删除该索引。

关于删除索引的其他API:

    DeleteDocuments(Query query):根据Query条件来删除单个或多个Document
    DeleteDocuments(Query[] queries):根据Query条件来删除单个或多个Document
    DeleteDocuments(Term term):根据Term来删除单个或多个Document
    DeleteDocuments(Term[] terms):根据Term来删除单个或多个Document
    DeleteAll():删除所有的Document

更新索引完整代码:

public class TestLuceneUpdateIndex {

    public static void main(String[] args) throws Exception {
        // 1. 准备中文分词器
        Analyzer analyzer = new SmartChineseAnalyzer();
        // 2. 索引
        Directory index = createIndex(analyzer);

        // 3. 查询器

        // 更新索引
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        IndexWriter indexWriter = new IndexWriter(index, config);
        Document doc = new Document();
        doc.add(new TextField("id", "51173", Field.Store.YES));
        doc.add(new TextField("name", "神鞭,鞭没了,神还在", Field.Store.YES));
        doc.add(new TextField("category", "道具", Field.Store.YES));
        doc.add(new TextField("price", "998", Field.Store.YES));
        doc.add(new TextField("place", "南海群岛", Field.Store.YES));
        doc.add(new TextField("code", "888888", Field.Store.YES));

        indexWriter.updateDocument(new Term("id", "51173"), doc);
        indexWriter.commit();
        indexWriter.close();

        Scanner s = new Scanner(System.in);
        while (true) {
            System.out.print("请输入查询关键字:");
            String keyword = s.nextLine();
            System.out.println("当前关键字是:" + keyword);
            Query query = new QueryParser("name", analyzer).parse(keyword);

            // 4. 搜索
            IndexReader reader = DirectoryReader.open(index);
            IndexSearcher searcher = new IndexSearcher(reader);
            int numberPerPage = 10;
            ScoreDoc[] hits = searcher.search(query, numberPerPage).scoreDocs;

            // 5. 显示查询结果
            showSearchResults(searcher, hits, query, analyzer);
            // 6. 关闭查询
            reader.close();
        }

    }

    private static void showSearchResults(IndexSearcher searcher, ScoreDoc[] hits, Query query, Analyzer analyzer) throws Exception {
        System.out.println("找到 " + hits.length + " 个命中.");

        SimpleHTMLFormatter simpleHTMLFormatter = new SimpleHTMLFormatter("<span style='color:red'>", "</span>");
        Highlighter highlighter = new Highlighter(simpleHTMLFormatter, new QueryScorer(query));

        System.out.println("找到 " + hits.length + " 个命中.");
        System.out.println("序号\t匹配度得分\t结果");
        for (int i = 0; i < hits.length; ++i) {
            ScoreDoc scoreDoc = hits[i];
            int docId = scoreDoc.doc;
            Document d = searcher.doc(docId);
            List<IndexableField> fields = d.getFields();
            System.out.print((i + 1));
            System.out.print("\t" + scoreDoc.score);
            for (IndexableField f : fields) {

                if ("name".equals(f.name())) {
                    TokenStream tokenStream = analyzer.tokenStream(f.name(), new StringReader(d.get(f.name())));
                    String fieldContent = highlighter.getBestFragment(tokenStream, d.get(f.name()));
                    System.out.print("\t" + fieldContent);
                } else {
                    System.out.print("\t" + d.get(f.name()));
                }
            }
            System.out.println("<br>");
        }
    }

    private static Directory createIndex(Analyzer analyzer) throws IOException {
        Directory index = new RAMDirectory();
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        IndexWriter writer = new IndexWriter(index, config);
        String fileName = "140k_products.txt";
        InputStream inputStream = ProductUtil.class.getClassLoader().getResourceAsStream(fileName);
//        InputStream inputStream = ProductUtil.class.getResourceAsStream("/"+fileName);
        List<Product> products = file2list(inputStream);
        int total = products.size();
        int count = 0;
        int per = 0;
        int oldPer = 0;
        for (Product p : products) {
            addDoc(writer, p);
            count++;
            per = count * 100 / total;
            if (per != oldPer) {
                oldPer = per;
                System.out.printf("索引中,总共要添加 %d 条记录,当前添加进度是: %d%% %n", total, per);
            }

        }
        writer.close();
        return index;
    }

    private static void addDoc(IndexWriter w, Product p) throws IOException {
        Document doc = new Document();
        doc.add(new TextField("id", String.valueOf(p.getId()), Field.Store.YES));
        doc.add(new TextField("name", p.getName(), Field.Store.YES));
        doc.add(new TextField("category", p.getCategory(), Field.Store.YES));
        doc.add(new TextField("price", String.valueOf(p.getPrice()), Field.Store.YES));
        doc.add(new TextField("place", p.getPlace(), Field.Store.YES));
        doc.add(new TextField("code", p.getCode(), Field.Store.YES));
        w.addDocument(doc);
    }
}

运行结果:

索引中,总共要添加 147939 条记录,当前添加进度是: 100% 
请输入查询关键字:鞭
当前关键字是:鞭
找到 5 个命中.
找到 5 个命中.
序号	匹配度得分	结果
1	7.4732623	51173	神<span style='color:red'>鞭</span>,<span style='color:red'>鞭</span>没了,神还在	道具	998	南海群岛	888888<br>
2	5.8898354	141769	圣喜酱牛<span style='color:red'>鞭</span>男性大爱开袋即食250克山东德州特产新鲜黄牛<span style='color:red'>鞭</span>非耗牛	零食会场	50.0	山东潍坊	45787754358<br>
3	4.530859	31289	欧舒丹马<span style='color:red'>鞭</span>草清新沐浴露250ml/500ml清爽清凉深层清洁男女	美妆主会场	180.0	浙江杭州	43062612851<br>
4	4.2535424	31290	欧舒丹唇膏 马<span style='color:red'>鞭</span>草清新润唇膏保湿滋润补水护唇膏 男女唇部护理	美妆主会场	85.0	浙江杭州	527371320856<br>
5	4.0082145	31291	欧舒丹身体乳 马<span style='color:red'>鞭</span>草润肤露润体乳液250ml柔肤保湿 清爽男士可用	美妆主会场	260.0	浙江杭州	42089347256<br>
请输入查询关键字:

我们把本次运行结果和上面第一次运行的结果对比,可以发现索引已经更新了。

Q.E.D.


擅长前端的Java程序员