Lucene学习

很早就听说Lucene的大名了,但一直没空研究,这几天比较闲,抽了一个下午时间,学习了一下Lucene,写了一个简单的Demo,总的感受是使用起来简单方便,在使用之前,首先要理解以下关键的类:

Document  
Document 是用来描述文档的,这里的文档可以指一个 HTML 页面,一封电子邮件,或者是一个文本文件。一个 Document 对象由多个 Field 对象组成的。可以把一个 Document 对象想象成数据库中的一个记录,而每个 Field 对象就是记录的一个字段。 
Field 
Field 对象是用来描述一个文档的某个属性的,比如一封电子邮件的标题和内容可以用两个 Field 对象分别描述。 
Analyzer  
在一个文档被索引之前,首先需要对文档内容进行分词处理,这部分工作就是由 Analyzer 来做的。Analyzer 类是一个抽象类,它有多个实现。针对不同的语言和应用需要选择适合的 Analyzer。Analyzer 把分词后的内容交给 IndexWriter 来建立索引。 
IndexWriter  
IndexWriter 是 Lucene 用来创建索引的一个核心的类,他的作用是把一个个的 Document 对象加到索引中来。 
Directory  
这个类代表了 Lucene 的索引的存储的位置,这是一个抽象类,它目前有两个实现,第一个是 FSDirectory,它表示一个存储在文件系统中的索引的位置。第二个是 RAMDirectory,它表示一个存储在内存当中的索引的位置。 

Query 
这是一个抽象类,他有多个实现,比如 TermQuery, BooleanQuery, PrefixQuery. 这个类的目的是把用户输入的查询字符串封装成 Lucene 能够识别的 Query。 

IndexSearcher  
IndexSearcher 是用来在建立好的索引上进行搜索的。它只能以只读的方式打开一个索引,所以可以有多个 IndexSearcher 的实例在一个索引上进行操作。

Hits 
Hits 是用来保存搜索结果的。  

理解了这些类之后,我写了一个简单的demo,包括索引构建和索引搜索,以后如果要做复杂的搜索,可以根据这个demo做扩展,是不是很简单哈。

1.开始导入相应的jar包

2.Demo编写

public class Item {
    private String id;
    private String title;
    private String content;

    public Item() {
    }

    public Item(String id, String title, String content) {
        this.id = id;
        this.title = title;
        this.content = content;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("[id=").append(id).append(",title=").append(title).append(",content=").append(content).append("]");
        return sb.toString();
    }
}

import java.io.File;
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.document.Field;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.DirectoryReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriterConfig;
import org.apache.lucene.queryparser.classic.MultiFieldQueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.apache.lucene.util.Version;

public class LuceneDemo {
    private boolean buildIndexer(Analyzer analyzer, Directory directory, List<Item> items) {
        IndexWriter iwriter = null;
        try {
            // 配置索引
            iwriter = new IndexWriter(directory, new IndexWriterConfig(Version.LUCENE_4_10_4, analyzer));
            // 删除所有document
            iwriter.deleteAll();
            // 将文档信息存入索引
            Document doc[] = new Document[items.size()];
            for (int i = 0; i < items.size(); i++) {
                doc[i] = new Document();

                Item item = items.get(i);
                java.lang.reflect.Field[] fields = item.getClass().getDeclaredFields();
                for (java.lang.reflect.Field field : fields) {
                    String fieldName = field.getName();
                    String getMethodName = "get" + toFirstLetterUpperCase(fieldName);
                    Object obj = item.getClass().getMethod(getMethodName).invoke(item);
                    doc[i].add(new Field(fieldName, (String) obj, TextField.TYPE_STORED));
                }
                iwriter.addDocument(doc[i]);
            }

        } catch (Exception e) {
            e.printStackTrace();
            return false;
        } finally {
            try {
                iwriter.close();
            } catch (IOException e) {
            }
        }
        return true;
    }

    /**
     * 72 * 根据keyword搜索索引 73 * @param analyzer 74 * @param directory 75 * @param
     * keyword 76 * @return 77
     */
    public List<Item> searchIndexer(Analyzer analyzer, Directory directory, String keyword) {
        DirectoryReader ireader = null;
        List<Item> result = new ArrayList<Item>();
        try {
            // 设定搜索目录
            ireader = DirectoryReader.open(directory);
            IndexSearcher isearcher = new IndexSearcher(ireader);

            // 对多field进行搜索
            java.lang.reflect.Field[] fields = Item.class.getDeclaredFields();
            int length = fields.length;
            String[] multiFields = new String[length];
            for (int i = 0; i < length; i++) {
                multiFields[i] = fields[i].getName();
            }
            MultiFieldQueryParser parser = new MultiFieldQueryParser(multiFields, analyzer);

            // 设定具体的搜索词
            Query query = parser.parse(keyword);
            ScoreDoc[] hits = isearcher.search(query, null, 10).scoreDocs;
            for (int i = 0; i < hits.length; i++) {
                Document hitDoc = isearcher.doc(hits[i].doc);
                Item item = new Item();
                for (String field : multiFields) {
                    String setMethodName = "set" + toFirstLetterUpperCase(field);
                    item.getClass().getMethod(setMethodName, String.class).invoke(item, hitDoc.get(field));
                }
                result.add(item);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        } finally {
            try {
                ireader.close();
                directory.close();
            } catch (IOException e) {
            }
        }
        return result;
    }

    /**
     * 首字母转大写
     *
     * @param str
     * @return
     */
    public static String toFirstLetterUpperCase(String str) {
        if (str == null || str.length() < 2) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1, str.length());
    }

    public static void main(String[] args) throws Exception {
        LuceneDemo demo = new LuceneDemo();
        Analyzer analyzer = new StandardAnalyzer();
        List<Item> items = new ArrayList<Item>();
        items.add(new Item("1", "first", "This is the text to be greatly indexed."));
        items.add(new Item("2", "second", "This is great"));
        items.add(new Item("3", "third", "I love apple and pear. "));
        items.add(new Item("4", "four", "我是中国人"));
        items.add(new Item("5", "five", "我叫何瑞"));

        // 索引存到内存中的目录
        // Directory directory = new RAMDirectory();
        // 索引存储到硬盘
        File file = new File("d:/lucene");
        Directory directory = FSDirectory.open(file);
        demo.buildIndexer(analyzer, directory, items);
        List<Item> result = demo.searchIndexer(analyzer, directory, "text");

        for (Item item : result) {
            System.out.println(item.toString());
        }
    }
}

测试结果

3.总结:

Lucene就是对目标数据进行索引创建和搜索的一个过程

标题基于SpringBoot+Vue的社区便民服务平台研究AI更换标题第1章引言介绍社区便民服务平台的研究背景、意义,以及基于SpringBoot+Vue技术的研究现状和创新点。1.1研究背景与意义分析社区便民服务的重要性,以及SpringBoot+Vue技术在平台建设中的优势。1.2国内外研究现状概述国内外在社区便民服务平台方面的发展现状。1.3研究方法与创新点阐述本文采用的研究方法和在SpringBoot+Vue技术应用上的创新之处。第2章相关理论介绍SpringBoot和Vue的相关理论基础,以及它们在社区便民服务平台中的应用。2.1SpringBoot技术概述解释SpringBoot的基本概念、特点及其在便民服务平台中的应用价值。2.2Vue技术概述阐述Vue的核心思想、技术特性及其在前端界面开发中的优势。2.3SpringBoot与Vue的整合应用探讨SpringBoot与Vue如何有效整合,以提升社区便民服务平台的性能。第3章平台需求分析与设计分析社区便民服务平台的需求,并基于SpringBoot+Vue技术进行平台设计。3.1需求分析明确平台需满足的功能需求和性能需求。3.2架构设计设计平台的整体架构,包括前后端分离、模块化设计等思想。3.3数据库设计根据平台需求设计合理的数据库结构,包括数据表、字段等。第4章平台实现与关键技术详细阐述基于SpringBoot+Vue的社区便民服务平台的实现过程及关键技术。4.1后端服务实现使用SpringBoot实现后端服务,包括用户管理、服务管理等核心功能。4.2前端界面实现采用Vue技术实现前端界面,提供友好的用户交互体验。4.3前后端交互技术探讨前后端数据交互的方式,如RESTful API、WebSocket等。第5章平台测试与优化对实现的社区便民服务平台进行全面测试,并针对问题进行优化。5.1测试环境与工具介绍测试
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值