首页 技术 正文
技术 2022年11月19日
0 收藏 899 点赞 4,800 浏览 7215 个字

接着全文检索Lucene (1) 。 下面我们来深入的研究一下,如何使用Lucene!

全文检索Lucene (1)中我们可以看出,Lucene就好比一个双向的工作流,一方面是对索引库的维护,另一方面是对查询过程的支持。同时,这也是Lucene的优雅所在。


Lucene索引库构建分析

Lucene查询过程分析

范例分析

下面我会写一个小的demo,大致的功能就是CRUD。类比JDBC,我们不可避免的要写一些工具类来优化我们的代码,减少重复代码。

Article.java

/** * @Date 2016年8月1日 * * @author Administrator */package domain;/** * @author 郭瑞彪 * */public class Article {    private Integer id;    private String title;    private String content;    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getTitle() {        return title;    }    @Override    public String toString() {        return "Article [id=" + id + ", title=" + title + ", content=" + content + "]";    }    public void setTitle(String title) {        this.title = title;    }    public String getContent() {        return content;    }    public void setContent(String content) {        this.content = content;    }}

LuceneUtils.java

/** * @Date 2016年8月1日 * * @author Administrator */package util;import java.io.IOException;import java.nio.file.Paths;import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.analysis.standard.StandardAnalyzer;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.search.IndexSearcher;import org.apache.lucene.store.Directory;import org.apache.lucene.store.FSDirectory;/** * @author 郭瑞彪 * */public class LuceneUtils {    private static Directory dir;    public static Directory getDir() {        return dir;    }    public static Analyzer getAnalyzer() {        return analyzer;    }    private static Analyzer analyzer;    /**     * 获得一个用于操作索引库的IndexWriter对象     *     * @return     */    public static IndexWriter getIndexWriter() {        try {            Directory dir = FSDirectory.open(Paths.get("./indexDir/"));            IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new StandardAnalyzer());            IndexWriter indexWriter = new IndexWriter(dir, indexWriterConfig);            return indexWriter != null ? indexWriter : null;        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return null;    }    /**     * 获得一个索引库查询对象     *     * @return     */    public static IndexSearcher getIndexSearcher() {        try {            DirectoryReader directoryReader = DirectoryReader.open(FSDirectory.open(Paths.get("./indexDir/")));            IndexReader indexReader = directoryReader;            IndexSearcher indexSearcher = new IndexSearcher(indexReader);            return indexSearcher != null ? indexSearcher : null;        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }        return null;    }    /**     * 释放IndexWriter资源     *     * @param indexWriter     */    public static void closeIndexWriter(IndexWriter indexWriter) {        try {            if (indexWriter != null) {                indexWriter.close();                indexWriter = null;            }        } catch (IOException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }    /**     * 释放IndexSearcher资源     *     * @param indexSearcher     */    public static void closeIndexSearcher(IndexSearcher indexSearcher) {        try {            if (indexSearcher != null) {                indexSearcher = null;            }        } catch (Exception e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }}

ArticleDocument.java

/** * @Date 2016年8月1日 * * @author Administrator */package util;import org.apache.lucene.document.Document;import org.apache.lucene.document.Field;import org.apache.lucene.document.Field.Store;import org.apache.lucene.document.StringField;import org.apache.lucene.document.TextField;import domain.Article;/** * @author 郭瑞彪 * */public class ArticleDocumentUtils {    /**     * Article转换成Licene的Document     *     * @param article     * @return     */    public static Document article2Document(Article article) {        Document doc = new Document();        doc.add(new StringField("id", article.getId().toString(), Store.YES));        doc.add(new TextField("title", article.getTitle(), Store.YES));        doc.add(new TextField("content", article.getContent(), Store.YES));        return doc != null ? doc : null;    }    /**     * 将Document转换回Article     *     * @param document     * @return     */    public static Article document2Article(Document document) {        Article a = new Article();        a.setId(Integer.parseInt(document.get("id")));        a.setTitle(document.get("title"));        a.setContent(document.get("content"));        return a != null ? a : null;    }}

ArticleIndexDao.java

/** * @Date 2016年8月1日 * * @author Administrator */package dao;import java.io.IOException;import java.util.ArrayList;import java.util.List;import org.apache.lucene.analysis.Analyzer;import org.apache.lucene.analysis.standard.StandardAnalyzer;import org.apache.lucene.document.Document;import org.apache.lucene.index.IndexWriter;import org.apache.lucene.index.Term;import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;import org.apache.lucene.queryparser.classic.QueryParser;import org.apache.lucene.search.IndexSearcher;import org.apache.lucene.search.Query;import org.apache.lucene.search.ScoreDoc;import org.apache.lucene.search.TopDocs;import org.apache.lucene.util.Version;import domain.Article;import domain.Page;import util.ArticleDocumentUtils;import util.LuceneUtils;/** * @author 郭瑞彪 * */public class ArticleIndexDao {    /**     * 将新的数据保存到索引库     *     * @param article     */    public void save(Article article) {        IndexWriter indexWriter = null;        try {            // 1. article --> document            Document doc = ArticleDocumentUtils.article2Document(article);            // 2. indexWriter.addDocument(document)            indexWriter = LuceneUtils.getIndexWriter();            indexWriter.addDocument(doc);            // 临时代码            indexWriter.close();        } catch (IOException e) {            throw new RuntimeException("ArticleIndexDao--save方法出错!\n" + e);        } finally {            LuceneUtils.closeIndexWriter(indexWriter);        }    }    /**     * 删除索引     *     * @param id     */    public void delete(Integer id) {        IndexWriter indexWriter = null;        try {            indexWriter = LuceneUtils.getIndexWriter();            indexWriter.deleteDocuments(new Term("id", id.toString()));        } catch (IOException e) {            throw new RuntimeException("ArticleIndexDao--save方法出错!\n" + e);        } finally {            LuceneUtils.closeIndexWriter(indexWriter);        }    }    /**     * 更新索引 <br>     * 更新操作代价很高,一般采取先删除对应的索引,然后在创建这个索引的方式     *     * @param article     */    public void update(Article article) {        IndexWriter indexWriter = null;        try {            Term term = new Term("id", article.getId().toString());            indexWriter = LuceneUtils.getIndexWriter();            // Document doc = new Document();            // doc.add(new TextField("title", article.getTitle(), Store.YES));            // doc.add(new TextField("content", article.getContent(),            // Store.YES));            // indexWriter.updateDocument(new Term("title", "content"), doc);            // 优化版本的实现就是:先删除愿索引,然后再创建该索引            indexWriter.deleteDocuments(term);            Document doc = ArticleDocumentUtils.article2Document(article);            indexWriter.addDocument(doc);        } catch (IOException e) {            throw new RuntimeException("ArticleIndexDao--save方法出错!\n" + e);        } finally {            LuceneUtils.closeIndexWriter(indexWriter);        }    }    /**     * 从索引库中查询     *     * @param queryString     *            查询字符串     * @return     */    public List<Article> search(String queryString) {        try {            // 1.queryString -->>Query            String[] queryFields = new String[] { "title", "content" };            Analyzer analyzer = new StandardAnalyzer();            analyzer.setVersion(Version.LUCENE_6_0_0.LUCENE_6_1_0);            QueryParser queryParser = new MultiFieldQueryParser(queryFields, analyzer);            Query query = queryParser.parse(queryString);            // 2. 查询,得到topDocs            IndexSearcher indexSearcher = LuceneUtils.getIndexSearcher();            TopDocs topDocs = indexSearcher.search(query, 100);            // 3.处理结果并返回            int totalHits = topDocs.totalHits;            ScoreDoc[] scoreDocs = topDocs.scoreDocs;            List<Article> articles = new ArrayList<Article>();            for (int i = 0; i < scoreDocs.length; i++) {                ScoreDoc scoreDoc = scoreDocs[i];                Document doc = indexSearcher.doc(scoreDoc.doc);                Article a = ArticleDocumentUtils.document2Article(doc);                articles.add(a);            }            LuceneUtils.closeIndexSearcher(indexSearcher);            return articles.size() > 0 ? articles : null;        } catch (Exception e) {            throw new RuntimeException("ArticleIndexDao-->> search方法出错!\n" + e);        }    }}

核心操作

关键点:我们在update索引库的时候会花费很大的代价。官网上也建议“先删掉相关索引项,然后在新建这个索引项”。注意Term的使用格式即可。

总结

经JUnit测试,代码可以正常的通过。

当然,代码中可以进行优化的地方还有很多,但是作为演示来说还是差强人意的吧。

希望对于Lucene6.1.0版本有困难的小伙伴能从中收获到自己需要的内容。

相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,088
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,565
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,413
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,186
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,822
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,905