Chapter 6. Manual index changes

简介: <div> <h2 style="orphans:2; widows:2; color:rgb(74,93,117); line-height:24px; margin-top:0em; font-family:'Lucida Grande',Geneva,Verdana,Arial,sans-serif; font-size:1.6em; text-align:justify"> <

Chapter 6. Manual index changes

hibernate search会检测hibernate core对数据库的操作,并且自动更新索引(除非EventListeners设置为disabled)。当然hibernate search也支持手动更新索引,来满足我们的需求。比如从备份数据中导入数据到数据库。则需手动建立索引

6.1. Adding instances to the index

Example 6.1. Indexing an entity via FullTextSession.index(T entity)

FullTextSession fullTextSession = Search.getFullTextSession(session);                     Transaction tx = fullTextSession.beginTransaction();                                      Object customer = fullTextSession.load( Customer.class, 8 );
fullTextSession.index(customer);
tx.commit(); //index only updated at commit time

如果要添加一个类索引的所有实例,或者所有类索引,推荐的方法是MassIndexer.see Section 6.3.2, “Using a MassIndexer” for more details.

我们可以通过api删除索引,这个操作叫做purging,清除。也是通过FullTextSession。

Example 6.2. Purging a specific instance of an entity from the index

FullTextSession fullTextSession = Search.getFullTextSession(session);                     Transaction tx = fullTextSession.beginTransaction();                                      for (Customer customer : customers) {                                                     fullTextSession.purge( Customer.class, customer.getId() );
}                                                                                         tx.commit(); //index is updated at commit time
purging通过id删除索引中的实体,不会影响到数据库
如果要删除一个索引的所有实例,可以使用purgeAll方法.

Example 6.3. Purging all instances of an entity from the index

FullTextSession fullTextSession = Search.getFullTextSession(session);                     Transaction tx = fullTextSession.beginTransaction();
fullTextSession.purgeAll( Customer.class );
//optionally optimize the index                                                           //fullTextSession.getSearchFactory().optimize( Customer.class );                          tx.commit(); //index changes are applied at commit time    

Note

FullTextEntityManager也有indexpurge and purgeAll 等方法

Note

所有手动索引方法 (indexpurge and purgeAll) 只影响索引, 然而它们任然有事务性,只有committed或者flushToindexes才能完成操作请求。

6.3. Rebuilding the whole index

如果实体和所以之间的映射被改变,那么就需要重建索引。比如新增了一个查询域。当数据库中导入新数据的时候,也需要重建索引。重建索引的方法有两种:
  1. 定期使用 FullTextSession.flushToIndexes()进行索引更新,或者使用 FullTextSession.index()更新实体。
  2. 使用MassIndexer.

6.3.1. Using flushToIndexes()

利用flushToIndexes可以刷新FullTextSession.puregeAll()已经删除的索引,和FullTextSession.index()添加索引实例到索引中。但是有一些内存和效率方面的问题。索引大量数据时,如果不周期性的利用flushToIndexes()清理队列请小心内存溢出。flushToIndexes()或者commit()之后,索引即被更新,并且无法rolled back.

Example 6.4. Index rebuilding using index() and flushToIndexes()

fullTextSession.setFlushMode(FlushMode.MANUAL);                                           fullTextSession.setCacheMode(CacheMode.IGNORE);                                           transaction = fullTextSession.beginTransaction();                                         //Scrollable results will avoid loading too many objects in memory                        ScrollableResults results = fullTextSession.createCriteria( Email.class )                    .setFetchSize(BATCH_SIZE)                                                                 .scroll( ScrollMode.FORWARD_ONLY );                                                    int index = 0 ;                                                                            while( results.next() ) {                                                                     index++;                                                                                  fullTextSession.index( results.get(0) ); //index each element                             if (index % BATCH_SIZE == 0) {                                                            fullTextSession.flushToIndexes(); //apply changes to indexes                              fullTextSession.clear(); //free memory since the queue is processed                       }                                                                                     }                                                                                        transaction.commit();
为了防止内存溢出,请使用setFetchSize(BATCH_SIZE),来限制。但是BATCH_SIZE越大,从数据库fetch的速度也越快。
hibernate search的MassIndexer方法利用多线程重建索引;你可以自由选择重载或者重建索引。这个方法的效率最高但是需要程序进入维护模式,不建议在进行MassIndexer的时候请求索引等操作。

Example 6.5. Index rebuilding using a MassIndexer

fullTextSession.createIndexer().startAndWait();
上面的操作将重建索引,删除原来的索引,重新从数据库中加载转化索引。虽然api使用很方便,但是建议添加一些额外配置来使进程加快。

Warning

MassIndexer期间索引将无法被请求,请求结果可能会丢失。

Example 6.6. Using a tuned MassIndexer

fullTextSession                                                                             .createIndexer( User.class )                                                               .batchSizeToLoadObjects( 25 )                                                                          .cacheMode( CacheMode.NORMAL )                                                                         .threadsToLoadObjects( 5 )                                                                             .idFetchSize( 150 )                                                                                    .threadsForSubsequentFetching( 20 )                                                                    .progressMonitor( monitor ) //a MassIndexerProgressMonitor implementation                              .startAndWait();
上面操作将重建所有User索引实例,并且将创建5个读数据库线程,每个query携带25个objects.由20个线程去读User的关联对象集。具体参数请见: Table 3.3, “Execution configuration” .
重建索引的时候推荐使用 CacheMode.IGNORE(默认),因为缓存对重建索引是额外消耗。当然某些数据类型下,开启缓存有助于效率,比如枚举类型
数据

Tip

效率最高的线程数量取决于你系统的整体结构, 数据库设计甚至数据的类型. 使用profiler可以帮助找到最佳线程数量: all internal thread groups have meaningful names to be easily identified with most tools.

Note

MassIndexer为了速度而生,且与实务无关,无需begin(),commit(). MassIndexer期间不建议用户查询,一来无法查询到结果,二来增加了系统负载.

其他一些影响索引效率和内存消耗的因素:
  • hibernate.search.[default|<indexname>].exclusive_index_use
  • hibernate.search.[default|<indexname>].indexwriter.max_buffered_docs
  • hibernate.search.[default|<indexname>].indexwriter.max_merge_docs
  • hibernate.search.[default|<indexname>].indexwriter.merge_factor
  • hibernate.search.[default|<indexname>].indexwriter.merge_min_size
  • hibernate.search.[default|<indexname>].indexwriter.merge_max_size
  • hibernate.search.[default|<indexname>].indexwriter.merge_max_optimize_size
  • hibernate.search.[default|<indexname>].indexwriter.merge_calibrate_by_deletes
  • hibernate.search.[default|<indexname>].indexwriter.ram_buffer_size
  • hibernate.search.[default|<indexname>].indexwriter.term_index_interval
上一个版本还支持 max_field_length,不过Lucene已经不支持了,可以使用 LimitTokenCountAnalyzer达到同样效果
所有   .indexwriter参数都是lucene定义的,hibernate search只不过传递这些参数。、详见 Section 3.6, “Tuning Lucene indexing performance”  
MassIndexer仅向前遍历加载的主键,但是mysql's jdbc driver会加载所有值到内存。为了最优化,请设置idFetchSize为Integer.MIN_VALUE

目录
相关文章
|
监控 Android开发 C语言
深度解读Android崩溃日志案例分析2:tombstone日志
深度解读Android崩溃日志案例分析2:tombstone日志
1239 0
|
前端开发
CSS - 使用 clip-path 轻松实现正六边形块状元素
如何使用CSS的`clip-path`属性来创建正六边形的块状元素。文章提供了详细的HTML和CSS代码示例,展示了如何实现六边形的布局和样式,并通过CSS动画增强了视觉效果。最终效果是一个包含文本的可交互的正六边形元素,当鼠标悬停时会改变颜色。
420 0
CSS - 使用 clip-path 轻松实现正六边形块状元素
|
SQL 安全 Linux
Centos7安装Docker搭建DVWA靶场
Centos7安装Docker搭建DVWA靶场
Centos7安装Docker搭建DVWA靶场
|
机器学习/深度学习 人工智能 编解码
【AI 生成式】生成对抗网络 (GAN) 的概念
【5月更文挑战第4天】【AI 生成式】生成对抗网络 (GAN) 的概念
【AI 生成式】生成对抗网络 (GAN) 的概念
|
SQL 缓存 Java
必知的技术知识:hsql数据库使用详解(入门)及快速使用
必知的技术知识:hsql数据库使用详解(入门)及快速使用
701 0
|
存储 运维 数据可视化
【技术分析】低代码平台的专有存储技术
低代码是一个新兴的技术,有着非常明确而鲜明的技术特点,比如:拖拽组件、可视化编程、零代码编程等等。但传统软件企业在进行技术融合时却往往是困难重重,旧有的技术积累很难能继承应用过来。本文作为一组技术分析,来逐一分解低代码背后的支撑技术。今天我们给大家带来的一个专题分析是,低代码平台的专有存储技术。
|
算法 计算机视觉
OpenCV(四十四):亚像素级别角点位置优化
OpenCV(四十四):亚像素级别角点位置优化
466 0
|
存储 关系型数据库 分布式数据库
PolarDB介绍
PolarDB是阿里巴巴自研的新一代云原生数据库
369 1
|
Shell Linux 开发工具
Windows下如何使用tree命令生成目录树
熟悉Linux的人应该对tree命令不陌生,可以使我们对指定目录制作一种目录树的形式,就像下面这种形式。
1854 0