索引的操作

我们建立所有就是要达到快速检索的目的,对数据能够方面便的查找,和数据库类似,索引也有自己的相关增删改查的操作。 
在索引的增删改查中,增删改属于写操作,主要是有IndexWrite提供的方法处理;而查显而易见,读操作,使用IndexSeacher 提供的方法来实现。在Lucene的官方文档找到 org.apache.lucene.index.IndexWriter 这个类,我们就可以看到他很多方法。

创建索引

如同上一章里面的代码,创建索引时先建立文件,创建索引的域,再使用IndexWriter的addDocument()方法就可以了,核心代码如下:

iwriter = new IndexWriter(directory, new IndexWriterConfig(version, new StandardAnalyzer(version)));

for(String text : content){ doc = new Document();

//使用的field 有很多类型,理解他们的区别 例如:TextField 和 StringField等

doc.add(new TextField("content", text,Field.Store.YES));

iwriter.addDocument(doc);

}

索引删除

索引删除包括只删除索引下面的document和删除索引文件 
在IndexWriter有如下一些方法

  1. deleteAll() 删除索引中所有的documents
  2. deleteDocuments(Query… queries) 按照提供的Query 删除documents
  3. deleteDocuments(Term… terms) 按照短语删除documents
  4. deleteUnusedFiles() 删除所有不再使用index的文件
  5. forceMergeDeletes() 删除处于已经删除的状态documents,由此可见,之前的删除文档的方法并没有真正的删除掉的documents,只是标记删除,我个人理解是类似逻辑上的删除
  6. forceMergeDeletes(boolean doWait) 删除过程中指明是否阻塞,直到操作完成

索引更新

更新操作也是一样,查看文档就有,这里截个图:

索引查询

Query 
索引查询的时候可以使用Query的实现子类来创建查询,执行IndexSearcher的search方法来查询,也可以使用QueryParse类来构造查询.

分页

  • 方式1:在scoreDoc中进行分页,数据一次性查出来,在结果集分页,结果集较大时容易溢出
  • 方式2:使用searcheAfter,等价查询的次数,但是不会出现查询结果溢出,推荐,类似数据库中的分页查询

这个类似数据库中的查询,可以对结果集分页显示,类似方式一,查询的时候直接分页,类似方式二 。

索引操作实例

package lucene_demo03;

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.CorruptIndexException;
import org.apache.lucene.index.DirectoryReader;
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.RAMDirectory;
import org.apache.lucene.util.Version;

/**
*
* 关于索引的查询(分页查询) 方式1:在scoreDoc中进行分页,数据一次性查出来,在结果集分页,结果集较大时容易溢出
* 方式2:使用searcheAfter,等价查询的次数,但是不会出现查询结果溢出,推荐,类似数据库中的分页查询
*
* @author YipFun
*/
public class LuceneDemo03
{

  private static final Version version = Version.LUCENE_4_9;
  private Directory directory = null;
  private DirectoryReader ireader = null;
  private IndexWriter iwriter = null;

  // 测试数据
  private String[] content = { "hello lucene", "I love coding", "I can play basketball", "I can play football", "I can play dota" };

  /**
  * 构造方法
  */
  public LuceneDemo03()
  {
    directory = new RAMDirectory();
  }

  /**
  * 创建索引
  */
  public void createIndex()
  {
    Document doc = null;
  try
  {
    iwriter = new IndexWriter(directory, new IndexWriterConfig(version, new StandardAnalyzer(version)));
    for (String text : content)
    {
      doc = new Document();
      // 使用的field 有很多类型,理解他们的区别 例如:TextField 和 StringField
      doc.add(new TextField("content", text, Field.Store.YES));
      iwriter.addDocument(doc);
    }

  } catch (IOException e)
  {
    e.printStackTrace();
  } finally
  {
    try
    {
      if (iwriter != null)
      iwriter.close();
    } catch (IOException e)
    {
      e.printStackTrace();
    }
  }

}

  public IndexSearcher getSearcher()
  {
  try
  {
    if (ireader == null)
    {
      ireader = DirectoryReader.open(directory);
    } else
    {
      DirectoryReader tr = DirectoryReader.openIfChanged(ireader);
      if (tr != null)
      {
        ireader.close();
        ireader = tr;
      }
    }
    return new IndexSearcher(ireader);
    } catch (CorruptIndexException e)
    {
      e.printStackTrace();
    } catch (IOException e)
    {
      e.printStackTrace();
    }
    return null;
  }

  /**
  *
  * @param field
  * @param term
  * @param num
  */
  public void searchByTerm(String field, String term, int num)
  {
    IndexSearcher isearcher = getSearcher();
    // 注意query的实现类和QueryParse的用法的区别
    TermQuery query = new TermQuery(new Term(field, term));
    ScoreDoc[] hits;
    try
    {
      // 注意searcher的几个方法
      hits = isearcher.search(query, null, num).scoreDocs;
      // Iterate through the results:
      for (int i = 0; i < hits.length; i++)
      {
        Document hitDoc = isearcher.doc(hits[i].doc);
        System.out.println("This is the text to be indexed=" + hitDoc.get("content"));
      }
    } catch (IOException e)
    {
      e.printStackTrace();
    }
  }

  /**
  * 区别与上一种查询,使用QueryParser的parse方法构造一个Query传递给方式使用
  *
  * @param query
  * @param num
  */
  public void searchByQueryParse(Query query, int num)
  {
    try
    {
      IndexSearcher searcher = getSearcher();
      TopDocs tds = searcher.search(query, num);
      System.out.println("一共查询了:" + tds.totalHits);
      for (ScoreDoc sd : tds.scoreDocs)
      {
        Document doc = searcher.doc(sd.doc);
        System.out.println("This is the text to be indexed=" + doc.get("content"));
      }
    } catch (CorruptIndexException e)
    {
       e.printStackTrace();
    } catch (IOException e)
    {
      e.printStackTrace();
    }
  }

  /**
  * 第一中分页方式,对ScoreDoc进行分页
  *
  * @param query
  * @param pageIndex
  * 从1开始,即第一页
  * @param pageSize
  * 分页大小
  * @param num
  * search top n hits
  */
  public void searchForPage(Query query, int pageIndex, int pageSize, int num)
  {
    try
    {
      IndexSearcher searcher = getSearcher();
      TopDocs tds = searcher.search(query, num);
      System.out.println("一共查询了:" + tds.totalHits);
      // 对ScoreDoc分页
      int start = (pageIndex - 1) * pageSize;
      int end = pageIndex * pageSize;
      ScoreDoc scoreDocs[] = tds.scoreDocs;
      for (int i = start; i < end; i++)
      {
        Document doc = searcher.doc(scoreDocs[i].doc);
        System.out.println("This is the text to be indexed=" + doc.get("content"));
      }
    } catch (CorruptIndexException e)
    {
        e.printStackTrace();
    } catch (IOException e)
    {
      e.printStackTrace();
    }
  }

  /**
  * 使用searchAfter 实现在查询的时候的分页
  *
  * @param query
  * @param pageIndex
  * @param pageSize
  * @throws IOException
  */
  public void searchForPageByAfter(Query query, int pageIndex, int pageSize) throws IOException
  {
    IndexSearcher searcher = getSearcher();
    // 先获取上一页的最后一个元素
     ScoreDoc lastSd = getLastScoreDoc(pageIndex, pageSize, query, searcher);
    TopDocs tds = searcher.searchAfter(lastSd, query, pageSize);
    for (ScoreDoc sd : tds.scoreDocs)
    {
      Document doc = searcher.doc(sd.doc);
      System.out.println("This is the text to be indexed=" + doc.get("content"));
    }

  }

  /**
  * 返回分页查询的上一条
  *
  * @param pageIndex
  * @param pageSize
  * @param query
  * @param indexSearcher
  * @return
  */
  private ScoreDoc getLastScoreDoc(int pageIndex, int pageSize, Query query, IndexSearcher searcher)
  {
    if (pageIndex == 1)
    return null;// 如果是第一页就返回空
    int num = pageSize * (pageIndex - 1);// 获取上一页的数量
    TopDocs tds = null;
    try
    {
      tds = searcher.search(query, num);
    } catch (IOException e)
    {
      e.printStackTrace();
  }
  return tds.scoreDocs[num - 1];
  }

  public static void main(String[] args) throws ParseException, IOException
  {
    LuceneDemo03 ld = new LuceneDemo03();
    ld.createIndex();
    ld.searchByTerm("content", "play", 500);
    System.out.println("==============1======================");

    QueryParser parser = new QueryParser(version, "content", new StandardAnalyzer(version));
    Query q = parser.parse("play");// 研究下parse的语法
    ld.searchByQueryParse(q, 500);
    System.out.println("===============2=====================");

    ld.searchForPage(q, 1, 2, 500);// 从第一页开始
    System.out.println("================3====================");

    ld.searchForPageByAfter(q, 1, 2);// 从第一页开始
    System.out.println("================4====================");
  }

}

转载于:https://www.cnblogs.com/downey/p/4890789.html

Lucene基础(二)--索引的操作相关推荐

  1. java中数组的返回值是什么类型_java基础学习:数组的常用操作与基础二维数组用法、及基本数据类型和引用数据类型赋值的区别...

    一.Arrays jdk中为了便于开发,给开发者提供了Arrays类,其中包含了很多数组的常用操作.例如快速输出.排序.查找等. 1.数组的常用方法 1.数组以字符串形式的输出,2.sort对数组排序 ...

  2. PHP从入门到跑路(二),基础语法,数据库操作

    基础语法 前言 一, 变量定义及使用 二,数据库操作 三, php开发细节躺坑 前言 博主不会php, 是从JAVA转过来的, PHP教程总结实际开发使用, 更加偏向于实际, 理论比较薄弱, 一直想总 ...

  3. Django基础五之Django模型层(二)多表操作

    Django基础五之Django模型层(二)多表操作 一 创建模型 表和表之间的关系 一对一.多对一.多对多 # 作者表 比较常用的信息放在这个表中 class Author(models.Model ...

  4. C语言 基础60题(2)——二维数组操作

    本篇内容主要是是对二维数组操作,掌握二维数组作为参数传递时,如何用指针表示. 第10题 double  sum_2diagonal(double* array_2d,  unsigned int m, ...

  5. Elasticsearch(一)——Es安装(三个必安工具、安装各种类型分词器)、Es 十大核心概念、通过 Kibana 操作 Es(中文分词、Es各种索引命令操作)

    Elasticsearch(一)--Es安装(三个必安工具.安装各种类型分词器).Es 十大核心概念.通过 Kibana 操作 Es(中文分词.Es各种索引命令操作) 一.Elasticsearch ...

  6. MariaDB基础(二)

    MariaDB基础(二) 介绍关于MariaDB的如下知识点: 1. 查询缓存 2. 索引 3. EXPLAIN 1.查询缓存: 1)什么是缓存? 缓存就是数据交换的缓冲区,即Cache,存放在内存中 ...

  7. apache lucene_Apache Lucene基础教程

    apache lucene 课程大纲 Apache Lucene是一个免费/开源信息检索软件库,它提供基于Java的索引和搜索技术,以及拼写检查,命中突出显示和高级分析/令牌化功能. Lucene是完 ...

  8. 建立索引lucene_用Lucene建立搜索索引

    建立索引lucene 本文是我们名为" Apache Lucene基础知识 "的学院课程的一部分. 在本课程中,您将了解Lucene. 您将了解为什么这样的库很重要,然后了解Luc ...

  9. Apache Lucene基础教程

    课程大纲 Apache Lucene是一个免费/开源信息检索软件库,它提供基于Java的索引和搜索技术,以及拼写检查,命中突出显示和高级分析/令牌化功能. Lucene是完全用Java编写的高性能,功 ...

最新文章

  1. Reids报错解决:Job for redis-server.service failed because the control process exited with error code.
  2. Docker run 命令【转】
  3. 审查元素上传php,KindEditor上传解析漏洞/列目录/内容漏洞_PHP教程
  4. html获取微信code,get-weixin-code.html
  5. 使用Docker 实现微服务并搭建博客,一文全掌握
  6. Qt图形界面编程入门(6)
  7. 数字图像处理-频域滤波-高通/低通滤波
  8. linux curl 特殊字符,遇到问题--curl--- url参数中有+、空格、=、%、、#等特殊符号的导致传参不全 | 易学教程...
  9. Python破解ZIP或RAR文件密码
  10. vins-mono中在rviz可视化下如何在world坐标系中让视角跟着相机移动
  11. spring.xml从外部文件引入数据库配置信息
  12. xml网站地图在线生成制作工具
  13. HUAWEI AC+AP设备配置
  14. python基础入门
  15. tumblr_如何将Google AdSense添加到您的Tumblr博客
  16. 8、Java中XML表示衣服尺码信息的文档编写
  17. errors potentially fixable with the `--fix` option报错的解决
  18. 前端基础面试题附答案
  19. 用计算机弹c哩c哩数字,C哩C哩 - 在线打字测试(dazi.kukuw.com)
  20. mybatis的example

热门文章

  1. 尚学堂java SE学习笔记(未完待续)
  2. 致终将火爆的NFC——ISO14443 TypeA(二)
  3. 功能点算法及在软件测试中的应用
  4. 完美的word转pdf
  5. [论文笔记|VIO]ICE-BA: Incremental, Consistent and Efficient Bundle Adjustment for Visual-Inertial SLAM
  6. 谷歌地球(Google Earth) 7.3.3.7721
  7. 如何将打开的多个excel文件,显示为独立窗口?
  8. arm64 blr指令
  9. 基于Matlab App Designer的语音信号分析与处理(二):IIR和FIR滤波器的设计,语音信号的滤波
  10. 《通用数据保护条例》(GDPR)系列解读五:出海欧洲,企业必须做好四大义务