bobo-browse

bobo-browse 是一款用java写的lucene扩展组件,通过它直接使用lucene建立的索引文件,就可以很方便的在lucene上实现分组统计功能。虽然lucene的使用已经很广泛,稳定性和效率方面都得到了大家的认可,但是在对搜索结果进行分组统计时就有些无能为力了。这样致使不少有需求的项目中,不得不修改lucene的源代码来实现分组统计的功能,要修改lucene源码首先必须对lucene的TopDocCollector类和排序原理有很深的理解,而且还要考虑多线程和性能的问题,如果你的项目中用到了compass,那还得修改compass的源代码,另外给后续的升级还会带来很多麻烦。 bobo-browse为了填补lucene在分组统计功能上的空缺,由此而诞生。早期的bobo-browse开源项目放在sourceforge上,后来被搬到google code上。目前项目地址为http://code.google.com/p/bobo-browse/

下载安装

<!-- start content -->

Get the source:

svn co https://bobo-browse.googlecode.com/svn/trunk bobo-trunk

Assuming checked out to ~/bobo-trunk: Build: Builds jars:

* cd ~/bobo-trunk
   * ant

Run cardemo app:

* In ~/bobo-trunk, do ant run-cardemo
   * cardemo should be deployed at: http://localhost:8888/cars/

cars.war is generated under cardemo/ Build Javadocs

* In ~/bobo-trunk, do ant javadoc
   * javadocs are generated under doc/

cardemo运行起来的效果(该例子中还用到了springMVC, springIOC,ajax技术DWR,总的索引数据是1.5W条)

测试代码:

package com.jobcn.test;
 
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
 
import org.apache.lucene.analysis.standard.StandardAnalyzer;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.SortField;
import org.apache.lucene.store.FSDirectory;
 
import com.browseengine.bobo.api.BoboBrowser;
import com.browseengine.bobo.api.BoboIndexReader;
import com.browseengine.bobo.api.Browsable;
import com.browseengine.bobo.api.BrowseFacet;
import com.browseengine.bobo.api.BrowseHit;
import com.browseengine.bobo.api.BrowseRequest;
import com.browseengine.bobo.api.BrowseResult;
import com.browseengine.bobo.api.FacetAccessible;
import com.browseengine.bobo.api.FacetSpec;
import com.browseengine.bobo.api.FacetSpec.FacetSortSpec;
import com.browseengine.bobo.facets.FacetHandler;
import com.browseengine.bobo.facets.impl.SimpleFacetHandler;
 
public class TestSearchPosByLucene {
 
   private static FSDirectory fsd;
 
	static {
		String indexDir = "/use/lucene/target/index/compos_0";
	    try {
			if(fsd == null){
	    	   fsd = FSDirectory.getDirectory(indexDir);
			}
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
 
	public void test(String keyWord) throws Exception{
 
        // reqworkyear facet handler
        SimpleFacetHandler reqworkyearHandler = new SimpleFacetHandler("reqworkyear");
 
        // reqdegreeid facet handler
        SimpleFacetHandler reqdegreeidHandler = new SimpleFacetHandler("reqdegreeid");
 
 
        List<FacetHandler> handlerList = Arrays.asList(new FacetHandler[]{reqworkyearHandler, reqdegreeidHandler});
 
        IndexReader reader = IndexReader.open(fsd,true);
 
          // decorate it with a bobo index reader
          BoboIndexReader boboReader = BoboIndexReader.getInstance(reader,handlerList);
 
          // creating a browse request
          BrowseRequest br=new BrowseRequest();
          br.setCount(5);
          br.setOffset(0);
 
          br.setFetchStoredFields(true);
 
          // parse a query
          QueryParser parser = new QueryParser("alltext",new StandardAnalyzer());
          Query q=parser.parse(keyWord);
          br.setQuery(q);
 
          SortField[] sortFields = new SortField[2]; //按学历+发布日期排序
          sortFields[0] = new SortField("reqdegreeid", SortField.INT, true);
          sortFields[1] = new SortField("postdate", SortField.STRING, true);
          br.setSort(sortFields);
 
 
          // add the facet output specs
          FacetSpec reqworkyearSpec = new FacetSpec();
          reqworkyearSpec.setOrderBy(FacetSortSpec.OrderHitsDesc);
 
          FacetSpec reqdegreeidSpec = new FacetSpec();
          reqdegreeidSpec.setMinHitCount(2);
          reqdegreeidSpec.setOrderBy(FacetSortSpec.OrderHitsDesc);
 
 
          br.setFacetSpec("reqworkyear",reqworkyearSpec);
          br.setFacetSpec("reqdegreeid",reqdegreeidSpec);
 
          long startTime = System.currentTimeMillis();
 
          // perform browse
          Browsable browser=new BoboBrowser(boboReader);
 
          BrowseResult result=browser.browse(br);
 
          int totalHits = result.getNumHits();
          System.out.println("公司发布的职位信息中含有‘"+keyWord+"’关键字的职位总数:" + totalHits);
           System.out.println("打印前"+ br.getCount() +"个职位Id:");
          BrowseHit[] hits = result.getHits();
          for(BrowseHit hit : hits){
            	System.out.println(hit.getStoredFields().get("$/compos/Id"));
           }
 
          Map<String,FacetAccessible> facetMap = result.getFacetMap();
 
          FacetAccessible colorFacets = facetMap.get("reqdegreeid");
          List<BrowseFacet> facetVals = colorFacets.getFacets();
          System.out.println("学历统计:");
          for(BrowseFacet facetVal : facetVals){
        	    System.out.println(facetVal.getValue() +"--->"+ facetVal.getHitCount() );  
            }
 
          FacetAccessible colorFacets2 = facetMap.get("reqworkyear");
          List<BrowseFacet> facetVals2 = colorFacets2.getFacets();
          System.out.println("工作经验统计:");
          for(BrowseFacet facetVal : facetVals2){
        	    System.out.println(facetVal.getValue() +"--->"+ facetVal.getHitCount() );  
            }
 
          long endTime = System.currentTimeMillis();
          System.out.println("总共用时:"+(endTime - startTime) + " ms"); 
	}
 
	public static void main(String args[]) throws Exception{
 
		TestSearchPosByLucene t = new TestSearchPosByLucene();
 
		t.test("软件工程师");
		t.test("销售");
		t.test("文员");
		t.test("程序员");
		t.test("机械");
		t.test("品质");
		t.test("采购");
		t.test("网络");
 
	}
 
}

测试结果(测试数据为464667条索引数据)

公司发布的职位信息中含有‘软件工程师’关键字的职位总数:4411

打印前5个职位Id:

146985307

1614164

147057728

146493293

146883100

学历统计:

50--->2850

40--->922

0--->541

60--->64

30--->20

20--->13

工作经验统计:

002--->1377

001--->967

003--->904

000--->894

005--->131

-100--->99

-001--->13

004--->12

008--->8

010--->3

006--->2

009--->1

总共用时:2203ms

职位信息中含有‘销售’关键字的职位总数:105705

打印前5个职位Id:

146746253

145398731

144558278

146676991

145903475

学历统计:

40--->53122

0--->20360

50--->19842

30--->7235

20--->4950

60--->189

70--->7

工作经验统计:

000--->32267

001--->24848

002--->23029

003--->15861

005--->6687

-100--->1575

008--->777

010--->324

-001--->145

004--->132

006--->46

007--->13

009--->1

总共用时:530ms

职位信息中含有‘文员’关键字的职位总数:8951

打印前5个职位Id:

147021795

1589251

1622088

1597617

1617689

学历统计:

40--->3207

0--->2172

30--->1837

20--->1230

50--->504

工作经验统计:

000--->3482

001--->2848

002--->1298

-100--->951

003--->306

005--->39

-001--->17

010--->4

004--->3

008--->2

006--->1

总共用时:187ms

职位信息中含有‘程序员’关键字的职位总数:2907

打印前5个职位Id:

147212315

136862380

145218476

146803412

146799915

学历统计:

50--->1111

40--->1093

0--->662

30--->25

60--->11

20--->5

工作经验统计:

001--->954

002--->860

000--->668

003--->330

005--->49

-100--->37

-001--->4

004--->3

008--->1

010--->1

总共用时:129ms

职位信息中含有‘机械’关键字的职位总数:21289

打印前5个职位Id:

1581752

1621668

1627486

147070171

147190901

学历统计:

40--->7886

50--->6918

0--->3535

30--->1992

20--->808

60--->145

70--->5

工作经验统计:

003--->5191

002--->4824

000--->3485

005--->3158

001--->2456

-100--->1182

008--->409

010--->283

004--->175

006--->75

007--->28

-001--->17

011--->5

009--->1

总共用时:155ms

职位信息中含有‘品质’关键字的职位总数:9401

打印前5个职位Id:

146711801

1618120

1621358

1621362

1621387

学历统计:

40--->3820

50--->2690

0--->1420

30--->755

20--->661

60--->54

工作经验统计:

003--->2307

002--->1970

000--->1479

005--->1384

001--->1309

-100--->464

008--->204

010--->135

004--->93

006--->38

007--->13

-001--->3

009--->2

总共用时:185ms

职位信息中含有‘采购’关键字的职位总数:10897

打印前5个职位Id:

146820815

146820816

1517476

1597948

1627281

学历统计:

40--->4872

50--->3172

0--->1612

30--->789

20--->416

60--->34

70--->2

工作经验统计:

003--->2637

002--->2365

000--->1872

001--->1767

005--->1520

-100--->318

008--->218

010--->116

004--->52

-001--->14

006--->13

007--->3

009--->2

总共用时:106ms

职位信息中含有‘网络’关键字的职位总数:36103

打印前5个职位Id:

1634505

1617099

146026202

145398731

146298700

学历统计:

40--->15922

50--->10997

0--->6604

30--->1665

20--->688

60--->218

70--->9

工作经验统计:

000--->9680

001--->9171

002--->8501

003--->5569

005--->2215

-100--->427

008--->202

-001--->142

010--->138

004--->40

006--->13

007--->4

009--->1

总共用时:121 ms

<!-- end content -->

相关推荐