了解Lucene(车辆名称映射Demo)

Lucene

源码地址:LuceneDemo码云

全文检索技术

传统搜索流程

在这里插入图片描述

基于Lucene搜索流程

在这里插入图片描述

1、Lucene

1.1、什么是Lucene

全文检索引擎工具包

通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式

1.2、主要功能

构建索引库(以数据库中的数据构建)
  • 创建文档

    将数据库查询的每条数据信息“赋值”给创建的每个Document对象

  • 分析文档,创建索引库

    处理生成的Document对象(包括:设置分词器,索引库生成路径)

    将生成的多个Document对象写入这个配置类

  • 索引库作用:就是通过关键字搜索,和被索引的分词进行比较,从未快速找到Document(文档)

  • 主要代码

    ps:查询的Car类型的list集合中,每一个car只有一个String类型的carName属性

    /*
        * 根据数据库数据建立索引库
        * */
        public static void createIndexDataBase(List<Car> cars) throws IOException {
            //1、采集数据
            //2、创建Document对象
            ArrayList<Document> documents = new ArrayList<>();
            for (Car car : cars) {
                Document document = new Document();
                // Document文档中添加Field域
                // 汽车名称
                // Store.YES:表示存储到文档域中
                document.add(new TextField("carName", car.getBName(), Field.Store.YES));
                // 把Document放到list中
                documents.add(document);
    
                // 3. 创建Analyzer分词器,分析文档,对文档进行分词
    //            Analyzer analyzer = new StandardAnalyzer();
                IKAnalyzer analyzer = new IKAnalyzer();
                // 4. 创建Directory对象,声明索引库的位置
                Directory directory = FSDirectory.open(Paths.get("/root/matengfei/demo/database/car"));
                // 5. 创建IndexWriteConfig对象,写入索引需要的配置
                IndexWriterConfig config = new IndexWriterConfig(analyzer);
                // 6.创建IndexWriter写入对象
                IndexWriter indexWriter = new IndexWriter(directory, config);
                // 7.写入到索引库,通过IndexWriter添加文档对象document
                for (Document doc : documents) {
                    indexWriter.addDocument(doc);
                }
                // 8.释放资源
                indexWriter.close();
            }
        }
    
查询索引库,返回结果
  • 封装关键字

  • 执行搜索

  • 主要代码

    public static String parseKey(String keyWord) throws IOException, ParseException {
            // 1. 创建Query搜索对象
            // 创建分词器
    //        Analyzer analyzer = new StandardAnalyzer();
            IKAnalyzer analyzer = new IKAnalyzer();
            // 创建搜索解析器,第一个参数:默认Field域,第二个参数:分词器
            QueryParser queryParser = new QueryParser("carName", analyzer);
    
            // 创建搜索对象
            Query query = queryParser.parse(keyWord);
    
            // 2. 创建Directory流对象,声明索引库位置
            Directory directory = FSDirectory.open(Paths.get("/root/matengfei/demo/database/car"));
            // 3. 创建索引读取对象IndexReader
            IndexReader reader = DirectoryReader.open(directory);
            // 4. 创建索引搜索对象
            IndexSearcher searcher = new IndexSearcher(reader);
            // 5. 使用索引搜索对象,执行搜索,返回结果集TopDocs
            // 第一个参数:搜索对象,第二个参数:返回的数据条数,指定查询结果最顶部的n条数据返回
            TopDocs topDocs = searcher.search(query, 1);
            System.out.println("查询到的数据总条数是:" + topDocs.totalHits);
            // 获取查询结果集
            ScoreDoc[] docs = topDocs.scoreDocs;
            String result = null;
            // 6. 解析结果集
            for (ScoreDoc scoreDoc : docs) {
                // 获取文档
                int docID = scoreDoc.doc;
                Document doc = searcher.doc(docID);
                System.out.println("=============================");
                System.out.println("id:" + docID);
                System.out.println("carName:" + doc.get("carName"));
                result = doc.get("carName");
            }
            reader.close();
            return result;
        }
    

1.3、底层结构

Lucene底层是一个倒排索引,这个索引结构主要分为两部分:索引和文档,通过关键字查询时,比较关键字和索引,从而找到对应文档。

索引
  • 一行目录就是一个索引,在Lucene中一个索引是放在一个文件夹中的
  • 一个索引由多个段组成
文档
  • 文档是建立索引的基本单位,一个段中可以包含多篇文档
域(Field)
  • 一篇文档包含不同类型的信息,也就是不同的域,比如一篇文章的标题、时间、描述等
Lucene3.0之前(跳表)

在这里插入图片描述

跳表原理类似于二分查找,前提是建立跳表之前(多级链表)底层原始链表有序

Lucene3.0之后(FST原理)

2、Lucene相关度排序

后续会更新基于Lucene实现博客系统相同兴趣和领域方向的博主推荐!!!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,下面是一个简单的 Lucene9 的示例代码,包括创建索引和搜索: ```java import java.io.IOException; 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.IndexWriter; import org.apache.lucene.index.IndexWriterConfig; import org.apache.lucene.index.Term; import org.apache.lucene.queryparser.classic.ParseException; 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.TermQuery; import org.apache.lucene.search.TopDocs; import org.apache.lucene.store.Directory; import org.apache.lucene.store.FSDirectory; import org.apache.lucene.store.RAMDirectory; import java.nio.file.Paths; public class LuceneDemo { public static void main(String[] args) throws IOException, ParseException { // 创建索引 Directory directory = FSDirectory.open(Paths.get("index")); IndexWriterConfig config = new IndexWriterConfig(new StandardAnalyzer()); IndexWriter writer = new IndexWriter(directory, config); Document doc1 = new Document(); doc1.add(new TextField("content", "Lucene is a full-text search engine library in Java", Field.Store.YES)); writer.addDocument(doc1); Document doc2 = new Document(); doc2.add(new TextField("content", "Lucene is used to build search applications", Field.Store.YES)); writer.addDocument(doc2); writer.close(); // 搜索 Directory directory2 = FSDirectory.open(Paths.get("index")); IndexSearcher searcher = new IndexSearcher(directory2); // TermQuery Query termQuery = new TermQuery(new Term("content", "search")); TopDocs topDocs = searcher.search(termQuery, 10); for (ScoreDoc scoreDoc : topDocs.scoreDocs) { Document doc = searcher.doc(scoreDoc.doc); System.out.println(doc.get("content") + " score: " + scoreDoc.score); } // QueryParser QueryParser parser = new QueryParser("content", new StandardAnalyzer()); Query query = parser.parse("Lucene search"); TopDocs topDocs2 = searcher.search(query, 10); for (ScoreDoc scoreDoc : topDocs2.scoreDocs) { Document doc = searcher.doc(scoreDoc.doc); System.out.println(doc.get("content") + " score: " + scoreDoc.score); } searcher.getIndexReader().close(); directory2.close(); } } ``` 以上代码创建了一个包含两条文档的索引,然后使用 TermQuery 和 QueryParser 分别进行了搜索,并打印出了搜索结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凉水不好喝

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值