Lucene--全文检索引擎工具包

1 篇文章 0 订阅

一、全文检索概述

1. 什么是全文检索
全文检索是指计算机索引程序通过扫描文章中的每一个词,对每一个词建立一个索引,指明该词在文章中出现的次数和位置,当用户查询时,检索程序就根据事先建立的索引进行查找,并将查找的结果反馈给用户的检索方式。这个过程类似于通过字典中的检索字表查字的过程。
常见的文件检索:Windows中的搜索功能、互联网搜索。

2. 数据分类
数据通常情况可以分为结构化数据和非结构化数据。
(1)结构化数据:具有固定的格式或有限长度的数据。例:存储在数据库中的数据、元数据。
(2)非结构化数据:没有固定格式或不定长度的数据。例:Word文档、磁盘中的文件、邮件。

3. 数据查询
数据查询通常也分为结构化数据查询和非结构化数据查询。
(1)结构化数据查询:通常使用 SQL 语句进行查询,而且能够快速得到查询结果。
结构化数据查询比较容易的原因:结构化数据的存储是有规律的,有行有列、格式固定、
长度固定。
(2)非机构化数据查询:通常分为顺序扫描和全文检索。
顺序扫描(Serial Scanning)
假设要查找内容包含某些字符串的文件,就是一个文档接着一个文档的看,对
于每一个文档,从头看到尾,如果该文档包含指定的字符串,则该文档即为要查找的文件。之后,接着看下一个文档,直到扫描完所有的文件。
例:使用 Windows 的搜索功能查找文件内容,速度相当慢。
全文检索(Full-text Search)
将非结构化数据中的一部分信息提取出来,重新组织,使其变得有一定结构,然后对有一
定结构的数据进行搜索,从而达到搜索相对较快目的。这部分从非结构化数据中提取出并
重新组织的信息,称为索引。
先建立索引,再对索引进行搜索的过程称为全文检索。

二、什么是Lucene

Lucene是apache软件基金会4 jakarta项目组的一个子项目,是一个开放源代码的全文检索引擎工具包,但它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,部分文本分析引擎(英文与德文两种西方语言)。Lucene的目的是为软件开发人员提供一个简单易用的工具包,以方便的在目标系统中实现全文检索的功能,或者是以此为基础建立起完整的全文检索引擎。Lucene是一套用于全文检索和搜寻的开源程式库,由Apache软件基金会支持和提供。Lucene提供了一个简单却强大的应用程式接口,能够做全文索引和搜寻。在Java开发环境里Lucene是一个成熟的免费开源工具。就其本身而言,Lucene是当前以及最近几年最受欢迎的免费Java信息检索程序库。人们经常提到信息检索程序库,虽然与搜索引擎有关,但不应该将信息检索程序库与搜索引擎相混淆。

二、Lucene实现全文检索流程

1. 索引和搜索流程图

绿色框表示创建索引,对要搜索的原始内容进行索引构建一个索引库,索引的过程:
确定原始内容(要所搜的内容)—》采集文档—》创建文档—》分析文档—》创建索引。

红色框表示查询索引,从索引库中搜索内容,搜索过程包括:
用户通过搜索界面—》创建查询—》执行查询(从索引库中搜索)—》渲染搜索结果。

2. 创建索引
对文档索引的过程,将用户需要搜索的内容进行索引,索引存储在索引库(index)中。
(1)获取原始文档
原始文档指的是索引和搜索的内容。

原始文档包含:
	搜索引擎:互联网上的网页
	站内搜索:数据库中的数据
	文件系统:磁盘中的文件

从互联网、数据库、文件系统中获取需要搜索的原始信息,这个过程称为信息采集。新宁夏采集的目的就是为了对原始文档进行索引。
(2)创建文档对象
在索引前需要将原始文档创建成文档对象(Document),文档中包含多个域(Field),域中存储原始文档数据。
Document中包含的域有file_name(文件名称)、file_path(文件路径)、file_content(文件内容)、file_size(文件大小)等。

注意:(1)每个Document可以有多个Field
   (2)不同的Document可以有不同的Field
   (3)同一个Document可以有相同的Field(域名和域值都相同)
   (4)每个文档都有一个唯一的编号,就是文档id。

(3)分析文档
分析文档的过程就是分词的过程。
将原始内容创建为包含多个域的文档,需要再对域中的内容进行解析,分析的过程是经过对原始文档去单词、将字母转为小写、去除标点符号、去除停用词等过程生成最终的词汇单元(单词列表),可以理解为一个一个的单词。
(4)创建索引
对文档分析所得出的词汇单元进行索引,索引的目的是为了搜索,最终要实现只需搜索被索引的词汇单元从而找到文档。

注意:(1)创建索引是对语汇单元索引,通过词语找文档,这种索引的结构叫倒排索引结构。
   (2)传统方法是根据文件找到该文件的内容,在文件内容中匹配搜索关键字,这种方法是顺序扫描方法,数据量大、搜索慢。
   (3)倒排索引结构是根据内容(词语)找文档

3. 查询索引
查询索引也是搜索的过程。搜索就是用户输入关键字,从索引(index)中进行搜索的过程。根据关键字搜索索引,根据索引找到对应的文档,从而找得到要搜索的内容。
(1)用户查询接口
全文检索系统提供用户搜索的界面供用户提交搜索的关键字,搜索完成展示搜索结构。
如:百度搜索

注意:Lucene不提供制作用户搜索界面的功能,需要根据自己的需求开发搜索界面。
(2)创建查询
用户输入查询关键字执行搜索之前需要先构建一个查询对象,查询对象中可以指定查询要搜索的Filed文档域、查询关键字等,查询对象会生成具体的查询语法。

例如:语法“fileName:lucene”表示要搜索 Field 域的内容为“lucene”的文档。
(3)执行查询
搜索索引过程:
根据查询语法在倒排索引词典表中分别找出对应搜索词的索引,从而找到索引所链接的文档链表。
例如:语法“fileName:lucene”表示要搜索处 fileName 域中包含 Lucene 的文档。其搜索过 程是在索引上查找域为 fileName 且关键在为 Lucene 的 Term,并根据 Term 找到文档 id 列表。
(4)渲染效果
以友好的界面将查询结果展示给用户,用户根据搜索结构找自己想要的信息,为了帮助用户能够找到自己所需的结果,提供了很多展示的效果。
例如在搜索结果中将关键字高亮显示,百度提供的百度快照、分页处理等。

注意:搜索结果默认按照相关度排序,相关度高的排在最前面,一般情况下,官方网站排在最前面。

三、Lucene入门

1. 搭建开发环境
下载lucene:
官网:https://lucene.apache.org/



下载lucene-8.5.2.zip并解压。

2. 入门案例
需求:实现本地文件搜索功能。
通过关键字搜索文件,所有文件名或文件内容中包含关键字的文件都需要搜索出来。

创建工程:

(1)创建索引

编码步骤:
1. 创建一个Director对象,指定保存索引库的位置。
2. 基于Director对象创建一个IndexWriter对象。
3. 读取磁盘上的文件,对应每一个文件创建一个Document对象。
4. 向文档对象中添加域。
5. 将文档对象写入索引库。
6. 关闭IndexWriter对象。
//创建索引
    public void testCreateIndex() throws IOException{
        //指定索引库的存放位置Directory对象
        Directory directory = FSDirectory.open(new File("E:\\programme\\test"));
        //索引库还可以存放到内存中
        //Directory directory = new RAMDirectory();

        //指定一个标准分析器,对文档内容进行分析
        Analyzer analyzer = new StandardAnalyzer();

        //创建indexwriterCofig对象
        //第一个参数: Lucene的版本信息,可以选择对应的lucene版本也可以使用LATEST
        //第二根参数:分析器对象
        IndexWriterConfig config = new IndexWriterConfig(Version.LATEST, analyzer);

        //创建一个indexwriter对象
        IndexWriter indexWriter = new IndexWriter(directory, config);

        //原始文档的路径
        File file = new File("E:\\programme\\searchsource");
        File[] fileList = file.listFiles();
        for (File file2 : fileList) {
            //创建document对象
            Document document = new Document();

            //创建field对象,将field添加到document对象中

            //文件名称
            String fileName = file2.getName();
            //创建文件名域
            //第一个参数:域的名称
            //第二个参数:域的内容
            //第三个参数:是否存储
            Field fileNameField = new TextField("fileName", fileName, Store.YES);

            //文件的大小
            long fileSize  = FileUtils.sizeOf(file2);
            //文件大小域
            Field fileSizeField = new LongField("fileSize", fileSize, Store.YES);

            //文件路径
            String filePath = file2.getPath();
            //文件路径域(不分析、不索引、只存储)
            Field filePathField = new StoredField("filePath", filePath);

            //文件内容
            String fileContent = FileUtils.readFileToString(file2, "utf-8");
            //文件内容域
            Field fileContentField = new TextField("fileContent", fileContent, Store.YES);

            document.add(fileNameField);
            document.add(fileSizeField);
            document.add(filePathField);
            document.add(fileContentField);
            //使用indexwriter对象将document对象写入索引库,此过程进行索引创建。并将索引和document对象写入索引库。
            indexWriter.addDocument(document);
        }
        //关闭IndexWriter对象。
        indexWriter.close();
    }

(2)查询索引

编码步骤:
1. 创建一个Directory对象,指定索引库的位置。
2. 创建一个IndexReader对象。
3. 创建一个IndexSearcher对象。
4. 创建一个Query对象,使用TermQuery创建。
5. 执行查询,获取TopDocs对象,使用TermQuery创建。
	a)	获取查询结果的总记录数
	b)	获取文档列表
6. 打印文档内容。
7. 关闭IndexReader对象。
//查询索引
    @Test
    public void testSearchIndex() throws IOException{
        //创建一个Directory对象,指定索引库存放的路径
        Directory directory = FSDirectory.open(new File("E:\\programme\\test"));
        //创建IndexReader对象,需要指定Directory对象
        IndexReader indexReader = DirectoryReader.open(directory);
        //创建Indexsearcher对象,需要指定IndexReader对象
        IndexSearcher indexSearcher = new IndexSearcher(indexReader);
        //创建一个TermQuery(精准查询)对象,指定查询的域与查询的关键词
        //创建查询
        Query query = new TermQuery(new Term("fileName", "apache"));
        //执行查询
        //第一个参数是查询对象,第二个参数是查询结果返回的最大值
        TopDocs topDocs = indexSearcher.search(query, 10);
        //查询结果的总条数
        System.out.println("查询结果的总条数:"+ topDocs.totalHits);
        //遍历查询结果
        //topDocs.scoreDocs存储了document对象的id
        //ScoreDoc[] scoreDocs = topDocs.scoreDocs;
        for (ScoreDoc scoreDoc : topDocs.scoreDocs) {
            //scoreDoc.doc属性就是document对象的id
            //int doc = scoreDoc.doc;
            //根据document的id找到document对象
            Document document = indexSearcher.doc(scoreDoc.doc);
            //文件名称
            System.out.println(document.get("fileName"));
            //文件内容
            System.out.println(document.get("fileContent"));
            //文件大小
            System.out.println(document.get("fileSize"));
            //文件路径
            System.out.println(document.get("filePath"));
            System.out.println("----------------------------------");
        }
        //关闭indexreader对象
        indexReader.close();
    }
}

四、分词器

1.英文分词器
特点:
(1)切分关键词
(2)去除停用词
(3)转为小写(搜索时不区分大小写,因为分词器进行了自动转化)

package com.demo;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.wltea.analyzer.lucene.IKAnalyzer;

/**
 * @author liu
 * @create 2020-07-01
 */
public class AnalyzerTest {
    /**
     * 查询英文分词器的效果
     * 使用默认的标准分词器StandardAnalyzer
     * @throws Exception
     */
    public void testEnAnalyzer() throws Exception{
        //1.创建一个Analyzer对象,StandardAnalyzer对象
	     Analyzer analyzer = new StandardAnalyzer();

        //2.使用分词器对象的tokenStream()方法获取TokenStream对象
        TokenStream tokenStream = analyzer.tokenStream("contentField","Lucene Core is a Java library providing powerful indexing and search features.");
        
        //3.向TokenStream对象中设置一个引用
        CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);

        //4.调用TokenStream对象的reset()方法
        tokenStream.reset();

        //5.遍历TokenStream对象
        while(tokenStream.incrementToken()){
            System.out.println(charTermAttribute.toString());
        }
        //6.关闭TokenStream对象
        tokenStream.close();
    }

    public static void main(String[] args) {
        AnalyzerTest test = new AnalyzerTest();
        try {
            test.testEnAnalyzer();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

2.中文分词器
(1)StandardAnalyzer
单字分词:按照中文一个字一个字地进行分词。
例如:“中文分词器”,分词后的结果:“中”、“文”、“分”、“词”、“器”

(2)SmartChineseAnalyzer
对中文支持较好,但是其扩展性较差:扩展词库、停用词库和同义词库不好处理。

(3)IK Analyzer
IK Analyzer 是一个开源的,基于 java 语言开发的轻量级的中文分词工具包。从 2006 年 12 月推出 1.0 版开始, IKAnalyzer 已经推出了 4 个大版本。最初,它是以开源项目 Luence 为应用主体的,结合词典分词和文法分析算法的中文分词组件。从 3.0 版本开始,IK 发展为面向 Java 的公用分词组件,独立于 Lucene项目,同时提供了对 Lucene 的默认优化实现。在 2012 版本中,IK 实现了简单的分词歧义排除算法,标志着 IK 分词器从单纯的词典分词向模拟语义分词衍化。

IK Analyzer 2012 特性:
采用了特有的“正向迭代最细粒度切分算法“,支持细粒度和智能分词两种切分模式;
在系统环境:Core2 i7 3.4G 双核,4G 内存,window 7 64 位, Sun JDK 1.6_29 64 位 普通 pc 环境测试,
IK2012 具有 160 万字/秒(3000KB/S)的高速处理能力。
2012 版本的智能分词模式支持简单的分词排歧义处理和数量词合并输出。
采用了多子处理器分析模式,支持:英文字母、数字、中文词汇等分词处理,兼容韩文、日文字符优化的词典存储,更小的内存占用。支持用户词典扩展定义。特别的,在 2012 版本,词典支持中文,英文,数字混合词语。

IKAnalyzer 使用步骤:

  1. 将 IKIKAnalyzer 的 jar 包添加到工程中。
  2. 将配置文件、扩展词典和停用词典添加到项目的 classpath 下。
    注意:扩展词典和停用词词典文件的编码格式是 UTF-8,严禁使用 Windows 记事本编辑,因为
    Windows 记事本编辑后得到的文件编码格式为 UTF-8+BOM。
  3. 使用 IKAnalyzer 进行分词。
package com.demo;

import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.analysis.TokenStream;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
import org.wltea.analyzer.lucene.IKAnalyzer;

/**
 * @author liu
 * @create 2020-07-01
 */
public class AnalyzerTest {
    /**
     * 查询中文分词器的效果
     * @throws Exception
     */
    public void testEnAnalyzer() throws Exception{
        //1.创建一个Analyzer对象,IKAnalyzer对象
        Analyzer analyzer = new IKAnalyzer();
        
        TokenStream tokenStream = analyzer.tokenStream("contentField", "Lucene是一套用于全文检索和搜寻的开源程序库,由Apache软件基金会支持和提供");
        
        //3.向TokenStream对象中设置一个引用
        CharTermAttribute charTermAttribute = tokenStream.addAttribute(CharTermAttribute.class);

        //4.调用TokenStream对象的reset()方法
        tokenStream.reset();

        //5.遍历TokenStream对象
        while(tokenStream.incrementToken()){
            System.out.println(charTermAttribute.toString());
        }
        //6.关闭TokenStream对象
        tokenStream.close();
    }

    public static void main(String[] args) {
        AnalyzerTest test = new AnalyzerTest();
        try {
            test.testEnAnalyzer();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

五、索引库操作

常用的 Field 域:

Field类数据类型Analyzed是否分区Indexed是否索引Stored是否存储说明
StringField(FiledName, FieldValue, Store.YES )字符串NYY/N该 Field 用来创建一个字符串Field,但是不进 行分词,会将整个字符串存储在索引库中(姓名、身份证号、订单号)
LongPoint(String name, long… point)LongYYN可以使用LongPoint、IntPoint 等类型存 储数值类型的数据。使得数值数据进行索引,但是不 能存储数据,若要存储,需要使用StoredField。
StoredField(FiledName, FieldValue)支持多种类型NNY该 Field 用来创建不同类型 Field,不分词,不索引,只存储。
TextField( FiledName, FieldValue, Store.NO)/TextField(FiledName,reader)字符串/字符流YYY/N若是一个 Reader,Lucene 猜测内容比较多,会采用Unstored 策略。

Field 域的属性
是否分词:是否对域的内容进行分词处理。
前提条件:对域的内容进行查询。

是否索引:将 Field 分析后的词或整个 Field 值进行索引,只有索引才可以搜索到。
例如:商品名称、商品简介分词后进行索引,姓名、身份证号、订单号不用分词但要索
引,作为查询条件。

是否存储:将 Field 值存储在文档中,存储在文档中的 Field 才能从 Document 中获取。
例如:商品名称、订单号,凡是后来要从 Document 中获取的 Field 都要存储。
标准:内容是否要展示给用户。
CRUD文档

package com.demo;

import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.LongPoint;
import org.apache.lucene.document.TextField;
import org.apache.lucene.index.*;
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.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.junit.Before;
import org.junit.Test;
import org.wltea.analyzer.lucene.IKAnalyzer;

import java.io.File;

/**
 * 索引库操作:CRUD
 * 1.添加文档
 * 2.删除文档
 * 3.修改文档
 * 4.查询文档
 *
 * @author liu
 * @create 2020-07-02
 */
public class IndexOperation {
    private IndexWriter indexWriter;
    private IndexReader indexReader;
    private IndexSearcher indexSearcher;

    @Before
    public void init() throws Exception{
        //创建Directory对象,索引库存放路径
        Directory directory = FSDirectory.open(new File("D:\\lucene\\index").toPath());
        //创建IndexWriterConfig对象,指定IKAnalyzer对象
        IndexWriterConfig indexWriterConfig = new IndexWriterConfig(new IKAnalyzer());
        //创建IndexWriter对象
        indexWriter = new IndexWriter(directory,indexWriterConfig);

        //创建IndexReader对象
        indexReader = DirectoryReader.open(directory);
        //创建IndexSearcher对象
        indexSearcher = new IndexSearcher(indexReader);
    }

    /**
     * 添加文档
     * @throws Exception
     */
    @Test
    public void addDoc() throws Exception{
        //创建Document对象
        Document document = new Document();

        //向文档中添加域
        document.add(new TextField("nameField","新建文本文档", Field.Store.YES));
        document.add(new TextField("contentField","新建文本文档的内容", Field.Store.YES));
        document.add(new TextField("pathField","D:\\\\lucene\\\\source", Field.Store.YES));

        //将文档写入索引库
        indexWriter.addDocument(document);

        //关闭索引库
        indexWriter.close();
    }

    /**
     * 删除文档
     * 1.删除所有文档
     * 2.根据查询删除文档
     * @throws Exception
     */
    @Test
    public void deleteAllDoc() throws Exception{
        //删除所有文档
        indexWriter.deleteAll();
        //关闭索引库
        indexWriter.close();
    }
    @Test
    public void deleteDocByQuery() throws Exception{
        //根据查询删除文档
        indexWriter.deleteDocuments(new Term("nameField","lucene"));
        //关闭索引库
        indexWriter.close();
    }

    /**
     * 修改文档
     * @throws Exception
     */
    @Test
    public void updateDoc() throws Exception{
        //创建新的文档对象
        Document document = new Document();

        //向文档中添加域
        document.add(new TextField("nameField", "修改后的文本文档", Field.Store.YES));
        document.add(new TextField("nameField1", "修改后的文本文档1", Field.Store.YES));
        document.add(new TextField("nameField2", "修改后的文本文档2", Field.Store.YES));

        //修改文档
        indexWriter.updateDocument(new Term("nameField","lucene"),document);

        //关闭索引库
        indexWriter.close();
    }
    /**
     * 查询文档
     * 使用 Query 的子类查询
	 * (1) TermQuery:根据关键词进行查询,需要指定查询的域及查询的关键字
	 * (2) RangeQuery:范围查询
     * @throws Exception
     */
    @Test
    public void rangeQuery() throws Exception{
        //创建Query对象
        Query query = LongPoint.newRangeQuery("sizeField",0L,1000L);
        this.printResult(query);
    }

    private void printResult(Query query) throws Exception{
        //执行查询
        TopDocs topDocs = indexSearcher.search(query,10);
        System.out.println("查询总记录数:"+topDocs.totalHits);

        ScoreDoc[] docs = topDocs.scoreDocs;
        for (ScoreDoc doc : docs) {
            //获取文档id
            int docId = doc.doc;
            //根据文档id获取文档对象
            Document document = indexSearcher.doc(docId);
            System.out.println("文件名称:" + document.get("nameField"));
            System.out.println("文件路径:" + document.get("pathField"));
            System.out.println("文件内容:" + document.get("contentField"));
            System.out.println("文件大小:" + document.get("sizeField"));
            System.out.println("---------------------------------------------------------");
        }
        indexReader.close();
    }

    /**
     * 查询文档
     * 使用 QueryParser 查询
	 *	可以对查询语句进行分词,然后基于分词的结果进行查询。
	 *	需要依赖 lucene-queryparser-8.5.2.jar
     * @throws Exception
     */
    @Test
    public void queryParser() throws Exception{
        /*
         * 创建QueryParser对象
         * 参数f:默认搜索域
         * 参数a:分词器对象
         */
        QueryParser queryParser = new QueryParser("nameField",new IKAnalyzer());

        //创建Query对象
        Query query = queryParser.parse("demo");
        //执行查询,打印结果
        this.printResult(query);
    }
}

六、Lucene核心API

1. IndexWriter
(1)利用这个类可以对索引库进行增、删、改操作。
(2)利用构造方法可以构造一个IndexWriter的对象

IndexWriter indexWriter =
 new IndexWriter(directory,LuceneConfig.analyzer,MaxFieldLength.LIMITED)

(3)addDocument 向索引库中添加一个Document
(4)updateDocument 更新一个Document
(5)deleteDocuments 删除一个指定的Document
(6)deleteAll 删除索引库中所有的Document

2. Directory
指向索引库的位置,有两种Directory
FSDirectory
(1)通过FSDirectory.open(new File("D:\lucene\index")) 建立的这个index文件夹,就是索引库存放的位置。
(2)通过这种方法建立索引库时如果index文件夹不存在,程序将自动创建一个,如果存在就用原本的这个。
(3)“优点:” 通过这个类可以知道所建立的索引库在磁盘上,能永久性的保存数据。
(4)“缺点”: 因为程序要访问磁盘上的数据,这个操作可能引发大量的IO操作,会降低性能。
RAMDirectory
(1)通过构造函数的形式Directory ramdirectory = new RAMDirectory(fsdirectory) 可以建立RAMDirectory。
(2)这种方法建立的索引库会在内存中开辟一定的空间,通过构造函数的形式吧FSDirectory移动到内存中。
(3)“缺点:”这种方法索引库中的数据是暂时的,只要内存的数据消失,这个索引库也就跟着消失了。
(4)“优点:”程序是在内存中跟索引库交互,因此通过该方式创建的索引的好处就在效率比较高,访问速度较快。

3. Document
(1)通过无参的构造函数可以创建一个Document对象。Document doc = new Document();
(2)一个Directory是由很多Document组成的。用户从客户端输入要搜索的关键内容被服务器端包装成JavaBean,然后再转化为Document。

4. Field
(1)Field相当于JavaBean的属性。
(2)Field的用法为:new Field(“title”,article.getTitle(),Store.YES,Index.ANALYZED)
第一个参数:属性;
第二个参数:属性值;
第三个参数:是否往索引库里存储;

第四个参数:是否更新索引;
a)NO 不进行索引
b)ANALYZED 进行分词索引
c)NOT_ANALYZED 进行索引,把整个输入作为一个词对待。

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值