空间站

北极心空

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  15 Posts :: 393 Stories :: 160 Comments :: 0 Trackbacks
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;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Query;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.hibernate.HibernateException;
import org.hibernate.search.SearchException;
import org.hibernate.search.reader.ReaderProvider;
import org.hibernate.search.reader.SharedReaderProvider;
import org.hibernate.search.store.DirectoryProvider;
import org.hibernate.search.store.FSDirectoryProvider;
import org.hibernate.search.store.IndexShardingStrategy;

public class LocalIndexDynamicShardingStrategy implements IndexShardingStrategy {
    private static Log log = LogFactory.getLog( LocalIndexDynamicShardingStrategy.class );
    private static final String LOCAL_FIELD = "artistCityId";
    private DirectoryProvider[] providers;
    private HashMap<String,DirectoryProvider> providerMap=new HashMap<String,DirectoryProvider>();
   
    public void initialize(Properties properties, DirectoryProvider[] providers) {
        this.providers = providers;
        localDirectoryToMap(null);
        System.out.println();
    }

    public DirectoryProvider[] getDirectoryProvidersForAllShards() {
        return mapToArray();
    }

    public DirectoryProvider getDirectoryProviderForAddition(Class entity,
            Serializable id, String idInString, Document document) {
        String key=docKey(document);
        return localDirectoryToMap(key);
    }

    public DirectoryProvider[] getDirectoryProvidersForDeletion(Class entity,
            Serializable id, String idInString, Document document) {
        String key=docKey(document);
        if(key.equals(""))return mapToArray();
        return new DirectoryProvider[] { localDirectoryToMap(key) };
    }

    public DirectoryProvider[] getDirectoryProvidersForSearch(Query query) {
        String key=docKey(query);
        if(key.equals(""))return mapToArray();
        return new DirectoryProvider[] { localDirectoryToMap(key) };
    }

    private DirectoryProvider[] mapToArray(){
        int size=providerMap.size();
        Collection<DirectoryProvider> dps=providerMap.values();
        return dps.toArray(new DirectoryProvider[size]);
    }
   
    private DirectoryProvider localDirectoryToMap(String key){
        LocalDirectoryProvider localdp=null;
        if(providers[0] instanceof LocalDirectoryProvider){
            localdp=(LocalDirectoryProvider) providers[0];
        }
        FSDirectory dir=localdp.getDirectory();
        File indexRoot=dir.getFile();
        if(key==null){
            File[] subIndex=indexRoot.listFiles();
            for(File sub:subIndex){
                localDirectoryToMap(sub.getName());
            }
            return localdp;
        }
        DirectoryProvider dp=providerMap.get(key);
        if(dp!=null)return dp;
        File indexFile=new File(indexRoot,key);
        String indexName="";
        boolean create = !indexFile.exists();
        FSDirectory directory = null;
        try {
            indexName=indexFile.getCanonicalPath();
            directory = FSDirectory.getDirectory( indexName );
            if ( create ) {
                log.debug( "Initialize index: '" + indexFile + "'" );
                IndexWriter iw = new IndexWriter( directory, new StandardAnalyzer(), create );
                iw.close();
            }
        } catch (IOException e) {
            throw new HibernateException( "Unable to initialize index: " + indexFile, e );
        }
        dp=new LocalDirectoryProvider(indexName,localdp.getIndexProps(),localdp.getSearchFactoryImplementor());
        ReaderProvider rp=localdp.getSearchFactoryImplementor().getReaderProvider();
        if(rp instanceof SharedReaderProvider)((SharedReaderProvider)rp).addLock(dp);
        providerMap.put(key, dp);
        return dp;
    }
   
    private String docKey(Document doc) {
        if(doc==null)return "";
        String sid = doc.get(LOCAL_FIELD);
        return sid;
    }

    private String docKey(Query query) {
        String sid = "";
        HashSet<Term> terms = new HashSet<Term>();
        query.extractTerms(terms);
        for (Term tr : terms) {
            if (tr.field().equals(LOCAL_FIELD)) {
                sid = tr.text();
                return sid;
            }
        }
        return sid;
    }
   
   
}
自定义静态目录分配实现类
复制内容到剪贴板
代码:
package com.search.store;

import java.io.File;
import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.Query;
import org.apache.lucene.store.Directory;
import org.apache.lucene.store.FSDirectory;
import org.hibernate.HibernateException;
import org.hibernate.search.SearchException;
import org.hibernate.search.store.DirectoryProvider;
import org.hibernate.search.store.FSDirectoryProvider;
import org.hibernate.search.store.IndexShardingStrategy;

public class LocalIndexStaticShardingStrategy implements IndexShardingStrategy {
    private static Log log = LogFactory.getLog( LocalIndexStaticShardingStrategy.class );
    private static final String LOCAL_FIELD = "artistCityId";
    private DirectoryProvider[] providers;
   
    public void initialize(Properties properties, DirectoryProvider[] providers) {
        this.providers = providers;
    }

    public DirectoryProvider[] getDirectoryProvidersForAllShards() {
        return providers;
    }

    public DirectoryProvider getDirectoryProviderForAddition(Class entity,
            Serializable id, String idInString, Document document) {
        int key=docKey(document);
        return providers[key];
    }

    public DirectoryProvider[] getDirectoryProvidersForDeletion(Class entity,
            Serializable id, String idInString, Document document) {
        int key=docKey(document);
        if(key==0)return providers;
        return new DirectoryProvider[] { providers[key] };
    }

    public DirectoryProvider[] getDirectoryProvidersForSearch(Query query) {
        int key=docKey(query);
        if(key==0)return providers;
        return new DirectoryProvider[] { providers[key] };
    }

    private int docKey(Document doc) {
        int fid = 0;
        if(doc==null)return fid;
        String sid = doc.get(LOCAL_FIELD);
        try {
            fid = Integer.parseInt(sid);
        } catch (NumberFormatException e) {
            throw new SearchException(LOCAL_FIELD + fid + " is not a number", e);
        }
        return fid;
    }

    private int docKey(Query query) {
        int fid = 0;
        HashSet<Term> terms = new HashSet<Term>();
        query.extractTerms(terms);
        for (Term tr : terms) {
            if (tr.field().equals(LOCAL_FIELD)) {
                String sid = tr.text();
                try {
                    fid = Integer.parseInt(sid);
                    return fid;
                } catch (NumberFormatException e) {
                    throw new SearchException(LOCAL_FIELD + fid
                            + " is not a number", e);
                }
            }
        }
        return fid;
    }
   
}
自定义DirectoryProvider实现类
复制内容到剪贴板
代码:
package com.search.store;

import java.io.File;
import java.io.IOException;
import java.util.Properties;
import java.util.concurrent.locks.ReentrantLock;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.store.FSDirectory;
import org.hibernate.HibernateException;
import org.hibernate.search.SearchException;
import org.hibernate.search.backend.LuceneIndexingParameters;
import org.hibernate.search.engine.SearchFactoryImplementor;
import org.hibernate.search.store.DirectoryProvider;
import org.hibernate.search.store.FSDirectoryProvider;
import org.hibernate.search.store.optimization.IncrementalOptimizerStrategy;
import org.hibernate.search.store.optimization.NoOpOptimizerStrategy;
import org.hibernate.search.store.optimization.OptimizerStrategy;
import org.hibernate.search.util.DirectoryProviderHelper;
import org.hibernate.util.StringHelper;

public class LocalDirectoryProvider extends FSDirectoryProvider{
    private static Log log = LogFactory.getLog( FSDirectoryProvider.class );
    private static String LUCENE_PREFIX = "hibernate.search.";
    private static String LUCENE_DEFAULT = LUCENE_PREFIX + "default.";
    private static final String MERGE_FACTOR = "merge_factor";
    private static final String MAX_MERGE_DOCS = "max_merge_docs";
    private static final String MAX_BUFFERED_DOCS = "max_buffered_docs";
    private static final String BATCH = "batch.";
    private static final String TRANSACTION = "transaction.";
    private static final String SHARDING_STRATEGY = "sharding_strategy";
    private static final String NBR_OF_SHARDS = SHARDING_STRATEGY + ".nbr_of_shards";
    private FSDirectory directory;
    private String indexName;
    private String directoryProviderName;
    private Properties indexProps;
    private SearchFactoryImplementor searchFactoryImplementor;
   
    public LocalDirectoryProvider(){}
   
    public LocalDirectoryProvider(String indexName,Properties indexProps, SearchFactoryImplementor searchFactoryImplementor){
        this.indexName=indexName;
        try {
            directory = FSDirectory.getDirectory( indexName );
        } catch (IOException e) {
            throw new HibernateException( "Unable to initialize index: " + indexName, e );
        }
        configureOptimizerStrategy(searchFactoryImplementor, indexProps, this);
        configureIndexingParameters(searchFactoryImplementor, indexProps, this);
        if ( !searchFactoryImplementor.getLockableDirectoryProviders().containsKey( this ) ) {
            searchFactoryImplementor.getLockableDirectoryProviders().put( this, new ReentrantLock() );
        }
    }
   
    public FSDirectory getDirectory() {
        return directory;
    }

    public void initialize(String directoryProviderName, Properties properties,
            SearchFactoryImplementor searchFactoryImplementor) {
        this.indexProps=properties;
        this.searchFactoryImplementor=searchFactoryImplementor;
        this.directoryProviderName=directoryProviderName;
        File indexDir = DirectoryProviderHelper.determineIndexDir( directoryProviderName, properties );
        try {
            boolean create = !indexDir.exists();
            if (create) {
                log.debug( "index directory not found, creating: '" + indexDir.getAbsolutePath() + "'" );
                indexDir.mkdirs();
            }
            indexName = indexDir.getCanonicalPath();
            directory = FSDirectory.getDirectory( indexName );
        }
        catch (IOException e) {
            throw new HibernateException( "Unable to initialize index: " + directoryProviderName, e );
        }

    }

    public void start() {
        super.start();
    }

    @Override
    public boolean equals(Object obj) {
        if ( obj == this ) return true;
        if ( obj == null || !( obj instanceof LocalDirectoryProvider ) ) return false;
        return indexName.equals( ( (LocalDirectoryProvider) obj ).indexName );
    }

    @Override
    public int hashCode() {
        int hash = 11;
        return 37 * hash + indexName.hashCode();
    }

    public Properties getIndexProps() {
        return indexProps;
    }

    public SearchFactoryImplementor getSearchFactoryImplementor() {
        return searchFactoryImplementor;
    }

    private void configureOptimizerStrategy(SearchFactoryImplementor searchFactoryImplementor, Properties indexProps, DirectoryProvider<?> provider) {
        boolean incremental = indexProps.containsKey( "optimizer.operation_limit.max" )
                || indexProps.containsKey( "optimizer.transaction_limit.max" );
        OptimizerStrategy optimizerStrategy;
        if (incremental) {
            optimizerStrategy = new IncrementalOptimizerStrategy();
            optimizerStrategy.initialize( provider, indexProps, searchFactoryImplementor);
        }
        else {
            optimizerStrategy = new NoOpOptimizerStrategy();
        }
        searchFactoryImplementor.addOptimizerStrategy(provider, optimizerStrategy);
    }
   
    private void configureIndexingParameters(SearchFactoryImplementor searchFactoryImplementor, Properties indexProps, DirectoryProvider<?> provider) {
      
        LuceneIndexingParameters indexingParams = new LuceneIndexingParameters();
        String s = indexProps.getProperty(TRANSACTION + MERGE_FACTOR);
      
        if (!StringHelper.isEmpty( s )) {
            try{
                indexingParams.setTransactionMergeFactor(Integer.valueOf(s));
                indexingParams.setBatchMergeFactor(Integer.valueOf(s));
            } catch (NumberFormatException ne) {
                throw new SearchException("Invalid value for " + TRANSACTION + MERGE_FACTOR + ": " + s);
            }
        }

        s = indexProps.getProperty(TRANSACTION + MAX_MERGE_DOCS);
        if (!StringHelper.isEmpty( s )) {
            try{
                indexingParams.setTransactionMaxMergeDocs(Integer.valueOf(s));
                indexingParams.setBatchMaxMergeDocs(Integer.valueOf(s));
            } catch (NumberFormatException ne) {
                throw new SearchException("Invalid value for " + TRANSACTION + MAX_MERGE_DOCS + ": " + s);
            }
        }
      
        s = indexProps.getProperty(TRANSACTION + MAX_BUFFERED_DOCS);
        if (!StringHelper.isEmpty( s )) {
            try{
                indexingParams.setTransactionMaxBufferedDocs(Integer.valueOf(s));
                indexingParams.setBatchMaxBufferedDocs(Integer.valueOf(s));
            } catch (NumberFormatException ne) {
                throw new SearchException("Invalid value for " + TRANSACTION + MAX_BUFFERED_DOCS + ": " + s);
            }
        }      
               
        s = indexProps.getProperty(BATCH + MERGE_FACTOR);
        if (!StringHelper.isEmpty( s )) {
            try{
                indexingParams.setBatchMergeFactor(Integer.valueOf(s));
            } catch (NumberFormatException ne) {
                throw new SearchException("Invalid value for " + BATCH + MERGE_FACTOR + ": " + s);
            }
        }
      
        s = indexProps.getProperty(BATCH + MAX_MERGE_DOCS);
        if (!StringHelper.isEmpty( s )) {
            try{
                indexingParams.setBatchMaxMergeDocs(Integer.valueOf(s));
            } catch (NumberFormatException ne) {
                throw new SearchException("Invalid value for " + BATCH + MAX_MERGE_DOCS + ": " + s);
            }
        }
      
        s = indexProps.getProperty(BATCH + MAX_BUFFERED_DOCS);
        if (!StringHelper.isEmpty( s )) {
            try{
                indexingParams.setBatchMaxBufferedDocs(Integer.valueOf(s));
            } catch (NumberFormatException ne) {
                throw new SearchException("Invalid value for " + BATCH + MAX_BUFFERED_DOCS + ": " + s);
            }
        }   
        searchFactoryImplementor.addIndexingParmeters(provider, indexingParams);
    }

    public String getIndexName() {
        return indexName;
    }
}
hibernate.properties
hibernate.search.default.directory_provider=org.hibernate.search.store.FSDirectoryProvider
hibernate.search.default.indexBase=/Hibernate/lucene/indexes
hibernate.search.analyzer=net.paoding.analysis.analyzer.PaodingAnalyzer
#开始静态目录分配,意思是预先设置目录的个数
hibernate.search.song.sharding_strategy.nbr_of_shards 28
hibernate.search.song.sharding_strategy com.blok.search.store.LocalIndexStaticShardingStrategy
#结束静态目录分配

#开始动态目录分配,意思是根据LocalIndexDynamicShardingStrategy实现类中doucment field值来分配
hibernate.search.song.sharding_strategy com.blok.search.store.LocalIndexDynamicShardingStrategy
hibernate.search.song.directory_provider com.blok.search.store.LocalDirectoryProvider
#结束动态目录分配

实体类
复制内容到剪贴板
代码:
package search.entity;

import java.io.Serializable;
import java.util.Date;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.search.annotations.DocumentId;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Store;

@Entity
@Table(name="song")
@Indexed(index="song")
@NamedQueries({
    @NamedQuery(name="Song.list[find]",query="from Song s order by s.time desc"),
    @NamedQuery(name="Song.list[count]",query="select count(*) from Song"),
    @NamedQuery(name="Song.byCityId[load]",query="from Song s where s.artistCityId =?")
})
public class Song implements Serializable{

    private static final long serialVersionUID = -1475639504643543299L;

    @Id
    @DocumentId
    @GeneratedValue(generator="system_uuid")
    @GenericGenerator(name="system_uuid",strategy="uuid")
    private String id;

    @Column(name="artist",length=36)
    private String artist;

    @Column(name="name",length=36,nullable=false)
    @Field(index=Index.TOKENIZED,store=Store.NO)
    private String name;

    @Lob
    @Column(name="lyric",length=2000)
    @Field(index=Index.TOKENIZED,store=Store.NO)
    private String lyric;

    @Column(name="time",nullable=false)
    @Field(index=Index.UN_TOKENIZED,store=Store.NO)
    private Date time;

    @Column(name="artistCityId",nullable=false)
    @Field(index=Index.UN_TOKENIZED,store=Store.YES)
    private Integer artistCityId;

    public String getArtist() {
        return artist;
    }

    public void setArtist(String artist) {
        this.artist = artist;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getLyric() {
        return lyric;
    }

    public void setLyric(String lyric) {
        this.lyric = lyric;
    }

    public Date getTime() {
        return time;
    }

    public void setTime(Date time) {
        this.time = time;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id=id;
    }

    public Integer getArtistCityId() {
        return artistCityId;
    }

    public void setArtistCityId(Integer artistCityId) {
        this.artistCityId = artistCityId;
    }

}
测试类
复制内容到剪贴板
代码:
package search.test;

import java.util.Date;
import java.util.List;

import net.paoding.analysis.analyzer.PaodingAnalyzer;

import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.MultiFieldQueryParser;
import org.apache.lucene.queryParser.ParseException;
import org.apache.lucene.search.BooleanClause;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import search.entity.Song;
import search.util.HibernateSessionFactory;

public class IndexTest {

    private Session session;

    @Before
    public void before(){
        session=HibernateSessionFactory.getSession();
    }

    @Test
    public void insert(){
        Transaction tx=session.beginTransaction();
        try {
            for(int i=0;i<1000;i++){
                Song song=new Song();
                song.setArtist("群星");
                song.setName("北京欢迎你");
                song.setLyric("北京欢迎你,welcome to beijing,第29届奥林匹克运动会");
                song.setTime(new Date());
                song.setArtistCityId(i%8);
                session.save(song);
                if(i%1000==0)session.flush();
            }
//            throw new RuntimeException("error");
        } catch (Exception e) {
            tx.rollback();
        }
        tx.commit();
    }

    @Test
    public void delete(){
        FullTextSession fullTextSession = Search.createFullTextSession(session);
        Transaction tx = fullTextSession.beginTransaction();
        List<Song> songs = session.getNamedQuery("Song.byCityId[load]").setInteger(0, 1).list();
        for (Song song : songs) {
            session.delete(song);
        }
        tx.commit();
     
    }

    @Test
    public void index(){
        FullTextSession fullTextSession = Search.createFullTextSession(session);
        Transaction tx = fullTextSession.beginTransaction();
        List<Song> songs = session.getNamedQuery("Song.list[find]").list();
        for (Song song : songs) {
            fullTextSession.index(song);
        }
        tx.commit();
     
    }

    @Test
    public void search() throws ParseException{
        FullTextSession fullTextSession = Search.createFullTextSession(session);
        Transaction tx = fullTextSession.beginTransaction();
        BooleanQuery booleanQuery=new BooleanQuery();
        MultiFieldQueryParser parser = new MultiFieldQueryParser( new String[]{"name", "lyric"},
          new PaodingAnalyzer());
        Query query = parser.parse( "北京欢迎你" );
        booleanQuery.add(query,BooleanClause.Occur.MUST);
        TermQuery tq=new TermQuery(new Term("artistCityId","0"));
        booleanQuery.add(tq,BooleanClause.Occur.MUST);
        org.hibernate.Query hibQuery = fullTextSession.createFullTextQuery( booleanQuery, Song.class );
        List<Song> songs = hibQuery.list();
//        for(Song song:songs){
//            System.out.println(song.getArtist()+":"+song.getName()+":"+song.getLyric());
//        }
        System.out.println("count:"+songs.size());
        tx.commit();
    }

    @Test
    public void purgeAll(){
        FullTextSession fullTextSession = Search.createFullTextSession(session);
        Transaction tx = fullTextSession.beginTransaction();
        fullTextSession.purgeAll( Song.class );
        tx.commit();
        fullTextSession.getSearchFactory().optimize(Song.class);
        fullTextSession.getSearchFactory().optimize();
    }

    @After
    public void close(){
        HibernateSessionFactory.closeSession();
    }
}
此上代码全部拷贝即可正常使用,如有不明之处,请回帖!

来源:http://www.rest4g.org/viewthread.php?tid=3&extra=page%3D1
posted on 2008-12-03 16:41 芦苇 阅读(1960) 评论(0)  编辑  收藏 所属分类: JAVAHibernate

只有注册用户登录后才能发表评论。


网站导航: