ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Lucene应用实战(二)——Field域的使用及索引库的维护

2022-01-24 13:59:09  阅读:221  来源: 互联网

标签:Document 索引 Lucene Field new document 分词


Field域的使用及索引库的维护

前言

在前面我们对Lucene的使用进行了简单的demo实战,本文我们详细来说明下Lucene中的Field域的使用及索引库维护的相关操作。

Fileld域的使用

简介

Lucene存储对象是以Document为存储单元,对象中相关的属性值则存放到Field中。

Field是文档中的域,包括Field名和Field值两部分,一个文档可以包括多个Field,Document只是Field
的一个承载体,Field值即为要索引的内容,也是要搜索的内容。

Field有三大属性:

  1. 是否分词(tokenized)
  • 是:作分词处理,即将Field值进行分词,分词的目的是为了索引

比如:商品名称、商品简介等,这些内容用户要输入关键字搜索,由于搜索的内容格式不固定、内容多需要
分词后将语汇单元索引。

  • 否:不做分词处理

​ 比如:订单号、身份证号等

  1. 是否索引(indexed)
  • 是:进行索引。将Field分词后的词或整个Field值进行索引,索引的目的是为了搜索。

    比如:商品名称、商品简介分词后进行索引,订单号、身份证号不用分词但要索引,这些将来都要作为查询
    条件。

  • 否:不索引。该域的内容无法搜索到。

    比如:文件路径、图片路径等,不用作为查询条件的不用索引。

  1. 是否存储(stored)
  • 是:将Field值存储在文档中,存储在文档中的Field才可以从Document中获取。

    比如:商品名称、订单号,凡是将来要从Document中获取的Field都要存储。

  • 否:不存储Field值,不存储的Field无法通过Document获取

    比如:商品简介,内容较大不用存储。如果要向用户展示商品简介可以从系统的关系数据库中获取商品简
    介。

    如果需要商品描述,则根据搜索出的商品ID去数据库中查询,然后显示出商品描述信息即可。

常用类型

Field对应的类是org.apache.lucene.document.Field,该类实现了org.apache.lucene.index.IndexableField接口,代表用于indexing的一个字段。Field类比较
底层一些,所以Lucene实现了许多Field子类,用于不同的场景。

Field的常用类型及用法如下表格所示:

Field类型 数据类型 是否分词 是否索引 是否存储 说明
StringField(FieldName, FieldValue, Store.YES) 字符串 N Y Y/N 字符串类型Field, 不分词, 作为一个整体进行索引(如: 身份证 号, 订单编号), 是否需要存储由Store.YES或Store.NO决定
TextField(FieldName, FieldValue, Store.NO) 文本类型 Y Y Y/N 文本类型Field, 分词并且索引, 是否需要存储由Store.YES或 Store.NO决定
LongField(FieldName, FieldValue, Store.YES) 或 LongPoint(String name, int… point)等 数值代表型 Y Y Y/N 在Lucene 6.0中,LongField替换为LongPoint,IntField替换 为IntPoint,FloatField替换为FloatPoint,DoubleField替换 为DoublePoint。对数值型字段索引,索引不存储。要存储结 合StoredField即可。
StoredField(FieldName, FieldValue) 支持多种类型 N N Y 构建不同类型的Field, 不分词, 不索引, 要存储. (如: 商品图片路 径)

Field应用代码

 @Test
    public void createIndex() throws Exception {
        // 1.采集数据
        Book  booka  = new Book();
        List<Book> bookList = new ArrayList<Book>();
        booka.setId(1);
        booka.setDesc("Lucene Core is a Java library providing powerful indexing and search features, as well as spellchecking, hit highlighting and advanced analysis/tokenization capabilities. The PyLucene sub project provides Python bindings for Lucene Core. ");
        booka.setName("Lucene");
        booka.setPrice(100.45f);
        bookList.add(booka);

        Book  bookb  = new Book();
        bookb.setId(11);
        bookb.setDesc("Solr is highly scalable, providing fully fault tolerant distributed indexing, search and analytics. It exposes Lucene's features through easy to use JSON/HTTP interfaces or native clients for Java and other languages. ");
        bookb.setName("Solr");
        bookb.setPrice(320.45f);
        bookList.add(bookb);
        Book  bookc  = new Book();
        bookc.setId(21);
        bookc.setDesc("The Apache Hadoop software library is a framework that allows for the distributed processing of large data sets across clusters of computers using simple programming models.");
        bookc.setName("Hadoop");
        bookc.setPrice(620.45f);
        bookList.add(bookc);

        // 2.将采集到的数据封装到Document对象中
        List<Document> docList = new ArrayList<>();
        Document document;
        for (Book book : bookList) {
            document = new Document();
            // IntPoint  分词 索引 不存储 存储结合  StoredField
            Field id = new IntPoint("id", book.getId());
            System.out.println(id.fieldType().tokenized() + ":" + id.fieldType().stored());
            Field id_v  = new StoredField("id", book.getId());
            // 分词、索引、存储 TextField
            Field name = new TextField("name", book.getName(), Field.Store.YES);
            // 分词、索引、不存储 但是是数字类型,所以使用FloatPoint
            Field price = new FloatPoint("price", book.getPrice());
            // 分词、索引、不存储 TextField
            Field desc = new TextField("desc",
                    book.getDesc(), Field.Store.YES);

            // 将field域设置到Document对象中

            document.add(id);
            document.add(id_v);
            document.add(name);
            document.add(price);
            document.add(desc);

            docList.add(document);
        }
        //3.创建Analyzer 分词器 对文档进行分词
        Analyzer  analyzer  = new StandardAnalyzer();
        // 创建Directory   和 IndexWriterConfig 对象
        Directory  directory = FSDirectory.open(Paths.get("D:/lucene/index"));

        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(analyzer);

        // 4.创建IndexWriter 写入对象
        IndexWriter  indexWriter = new IndexWriter(directory,indexWriterConfig);

        // 添加文档对象
        for (Document doc : docList) {
            indexWriter.addDocument(doc);
        }
        // 释放资源
        indexWriter.close();
    }

索引库的维护

索引添加

索引添加是新增索引库中不存在的索引记录,代码如下:

@Test
    public  void  indexCreate()throws  Exception{
        // 创建分词器
        Analyzer analyzer = new StandardAnalyzer();
        // 创建Directory 流对象
        Directory directory = FSDirectory.open(Paths.get("D:/lucene/index3"));
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        // 创建索引写入对象
        IndexWriter  indexWriter = new IndexWriter(directory,config);
        // 创建Document
        Document  document = new Document();
        document.add(new TextField("id","1001", Field.Store.YES));
        document.add(new TextField("name","game", Field.Store.YES));
        document.add(new TextField("desc","one world one dream", Field.Store.YES));
        // 添加文档 创建索引
        indexWriter.addDocument(document);
        indexWriter.close();
    }

索引更新

更新索引是先删除再添加,建议对更新需求采用此方法并且要保证对已存在的索引执行更新,可以先查
询出来,确定更新记录存在执行更新操作。
如果更新索引的目标文档对象不存在,则执行添加

代码如下:

 @Test
    public  void  indexUpdate()throws  Exception{
        // 创建分词器
        Analyzer analyzer = new StandardAnalyzer();
        // 创建Directory 流对象
        Directory directory = FSDirectory.open(Paths.get("D:/lucene/index3"));
        IndexWriterConfig config = new IndexWriterConfig(analyzer);
        // 创建索引写入对象
        IndexWriter  indexWriter = new IndexWriter(directory,config);
        // 创建Document
        Document  document = new Document();

        document.add(new TextField("id","1001", Field.Store.YES));
        document.add(new TextField("name","好好学习", Field.Store.YES));
        document.add(new TextField("desc","游戏结束该干啥干啥去", Field.Store.YES));
        // 更新
        indexWriter.updateDocument(new Term("name","game"),document);
        indexWriter.close();

    }

索引删除

根据Term项删除索引,满足条件的将全部删除。

示例:indexWriter.deleteDocuments(new Term("name", "game"));

全部删除

清空索引库中的所有索引:

indexWriter.deleteAll();

源码

lucene索引实战demo

总结

本文我们主要学习了Lucene中Field域的使用,常用的几种Field类型,及索引库的增删改操作。

更多

更多我亲身经历的面试真题、学习资料,还有想要内推大厂的小伙伴可以联系我,请关注微信公众号:【程序员资料站】,回复关键字 “面试”或者“资料” 获取更多学习资料,回复“内推”,我帮你内推大厂。

标签:Document,索引,Lucene,Field,new,document,分词
来源: https://blog.csdn.net/yongbutingxide/article/details/122666061

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有