TEAM : I.S.T.O
AUTHOR : Jerry
hibernate search采用apache lucene做全文索引,在3.0版本中,hibernate search 只支持对个单个实体单个目录和通过hash算法来定位目录,进行索引的添加,而删除是查找所有子目录,对于更新操作也是先删除后添加。这种情况对于某些索 引结构可以按特定规则来划分的情况,性能上不是太适合。本来是可以通过实现IndexShardingStrategy和 DirectoryProvider这两个接口来完成自定义目录搜索。但是IndexShardingStrategy这个接口开放的方法很局限性。我已 经将这个接口的定义建议提交给了hibernate search Team,可能他们没有考虑到这种情况。我自己动手修改了hibernate search 3.0.1的源代码来实现。
// $Id: IndexShardingStrategy.java 14012 2007-09-16 19:57:36Z hardy.ferentschik $
package org.hibernate.search.store;
import java.io.Serializable;
import java.util.Properties;
import org.apache.lucene.document.Document;
import org.apache.lucene.search.Query;
/**
* Defines how a given virtual index shards data into different DirectoryProviders
*
* @author Emmanuel Bernard
*/
public interface IndexShardingStrategy {
/**
* provides access to sharding properties (under the suffix sharding_strategy)
* and provide access to all the DirectoryProviders for a given index
*/
void initialize(Properties properties, DirectoryProvider[] providers);
/**
* Ask for all shards (eg to query or optimize)
*/
DirectoryProvider[] getDirectoryProvidersForAllShards();
/**
* return the DirectoryProvider where the given entity will be indexed
*/
DirectoryProvider getDirectoryProviderForAddition(Class entity, Serializable id, String idInString, Document document);
/**
* return the DirectoryProvider(s) where the given entity is stored and where the deletion operation needs to be applied
* id and idInString can be null. If null, all the directory providers containing entity types should be returned
*/
/***********hibernate search code**********
DirectoryProvider[] getDirectoryProvidersForDeletion(Class entity, Serializable id, String idInString);
*****************************************/
/****************add by Jerry*************/
public DirectoryProvider[] getDirectoryProvidersForDeletion(Class entity,Serializable id, String idInString, Document document);
public DirectoryProvider[] getDirectoryProvidersForSearch(Query query);
/*****************************************/
}
修改这接口后,一些相关的引用和实现类要进行修改,原来本身实现类加上参数签名就可以。
org.hibernate.search.query.FullTextQueryImpl类的buildSearcher方法中的代码
/***********hibernate search code**********
final DirectoryProvider[] directoryProviders =
builder.getDirectoryProviderSelectionStrategy().getDirectoryProvidersForAllShards();
*****************************************/
/****************add by Jerry*************/
final DirectoryProvider[] directoryProviders =
builder.getDirectoryProviderSelectionStrategy().getDirectoryProvidersForSearch(luceneQuery);
/*****************************************/
org.hibernate.search.backend.impl.lucene.LuceneBackendQueueProcessor更改接口相应方法名
org.hibernate.search.store.DirectoryProviderFactory类的createDirectoryProviders方法中的代码
/***********hibernate search code**********
for (Map.Entry entry : indexProps[0].entrySet()) {
if ( ( (String) entry.getKey() ).startsWith( SHARDING_STRATEGY ) ) {
shardingProperties.put( entry.getKey(), entry.getValue() );
}
}
******************************************/
/****************add by Jerry*************/
for (String key : indexProps[0].stringPropertyNames()) {
if ( key.startsWith( SHARDING_STRATEGY ) ) {
shardingProperties.put( key, indexProps[0].getProperty(key) );
}
}
/*****************************************/
org.hibernate.search.reader.SharedReaderProvider类的initialize方法中的代码
/***********hibernate search code**********
perDirectoryProviderManipulationLocks = Collections.unmodifiableMap( perDirectoryProviderManipulationLocks );
******************************************/
}
/****************add by Jerry*************/
public void addLock(DirectoryProvider dp){
if(perDirectoryProviderManipulationLocks.get(dp)==null)
perDirectoryProviderManipulationLocks.put( dp, new ReentrantLock() );
}
/*****************************************/
自定义动态目录分配实现类
package com.search.store;
import java.io.File;
import java.io.IOException
AUTHOR : Jerry
hibernate search采用apache lucene做全文索引,在3.0版本中,hibernate search 只支持对个单个实体单个目录和通过hash算法来定位目录,进行索引的添加,而删除是查找所有子目录,对于更新操作也是先删除后添加。这种情况对于某些索 引结构可以按特定规则来划分的情况,性能上不是太适合。本来是可以通过实现IndexShardingStrategy和 DirectoryProvider这两个接口来完成自定义目录搜索。但是IndexShardingStrategy这个接口开放的方法很局限性。我已 经将这个接口的定义建议提交给了hibernate search Team,可能他们没有考虑到这种情况。我自己动手修改了hibernate search 3.0.1的源代码来实现。
// $Id: IndexShardingStrategy.java 14012 2007-09-16 19:57:36Z hardy.ferentschik $
package org.hibernate.search.store;
import java.io.Serializable;
import java.util.Properties;
import org.apache.lucene.document.Document;
import org.apache.lucene.search.Query;
/**
* Defines how a given virtual index shards data into different DirectoryProviders
*
* @author Emmanuel Bernard
*/
public interface IndexShardingStrategy {
/**
* provides access to sharding properties (under the suffix sharding_strategy)
* and provide access to all the DirectoryProviders for a given index
*/
void initialize(Properties properties, DirectoryProvider[] providers);
/**
* Ask for all shards (eg to query or optimize)
*/
DirectoryProvider[] getDirectoryProvidersForAllShards();
/**
* return the DirectoryProvider where the given entity will be indexed
*/
DirectoryProvider getDirectoryProviderForAddition(Class entity, Serializable id, String idInString, Document document);
/**
* return the DirectoryProvider(s) where the given entity is stored and where the deletion operation needs to be applied
* id and idInString can be null. If null, all the directory providers containing entity types should be returned
*/
/***********hibernate search code**********
DirectoryProvider[] getDirectoryProvidersForDeletion(Class entity, Serializable id, String idInString);
*****************************************/
/****************add by Jerry*************/
public DirectoryProvider[] getDirectoryProvidersForDeletion(Class entity,Serializable id, String idInString, Document document);
public DirectoryProvider[] getDirectoryProvidersForSearch(Query query);
/*****************************************/
}
修改这接口后,一些相关的引用和实现类要进行修改,原来本身实现类加上参数签名就可以。
org.hibernate.search.query.FullTextQueryImpl类的buildSearcher方法中的代码
/***********hibernate search code**********
final DirectoryProvider[] directoryProviders =
builder.getDirectoryProviderSelectionStrategy().getDirectoryProvidersForAllShards();
*****************************************/
/****************add by Jerry*************/
final DirectoryProvider[] directoryProviders =
builder.getDirectoryProviderSelectionStrategy().getDirectoryProvidersForSearch(luceneQuery);
/*****************************************/
org.hibernate.search.backend.impl.lucene.LuceneBackendQueueProcessor更改接口相应方法名
org.hibernate.search.store.DirectoryProviderFactory类的createDirectoryProviders方法中的代码
/***********hibernate search code**********
for (Map.Entry entry : indexProps[0].entrySet()) {
if ( ( (String) entry.getKey() ).startsWith( SHARDING_STRATEGY ) ) {
shardingProperties.put( entry.getKey(), entry.getValue() );
}
}
******************************************/
/****************add by Jerry*************/
for (String key : indexProps[0].stringPropertyNames()) {
if ( key.startsWith( SHARDING_STRATEGY ) ) {
shardingProperties.put( key, indexProps[0].getProperty(key) );
}
}
/*****************************************/
org.hibernate.search.reader.SharedReaderProvider类的initialize方法中的代码
/***********hibernate search code**********
perDirectoryProviderManipulationLocks = Collections.unmodifiableMap( perDirectoryProviderManipulationLocks );
******************************************/
}
/****************add by Jerry*************/
public void addLock(DirectoryProvider dp){
if(perDirectoryProviderManipulationLocks.get(dp)==null)
perDirectoryProviderManipulationLocks.put( dp, new ReentrantLock() );
}
/*****************************************/
自定义动态目录分配实现类
package com.search.store;
import java.io.File;
import java.io.IOException