Lucene有内置的排序用IndexSearcher.search(query,sort)但是功能并不理想。我们需要自己实现自定义的排序。
这样的话得实现两个接口: ScoreDocComparator, SortComparatorSource
用IndexSearcher.search(query,new Sort(new SortField(String Field,SortComparatorSource)));
就看个例子吧:
这是一个建立索引的例子:
public void IndexSort() throws IOException { IndexWriter writer = new IndexWriter("C://indexStore",new StandardAnalyzer(),true); Document doc = new Document(); doc.add(new Field("sort","1",Field.Store.YES,Field.Index.TOKENIZED)); writer.addDocument(doc); doc = new Document(); doc.add(new Field("sort","4",Field.Store.YES,Field.Index.TOKENIZED)); writer.addDocument(doc); doc = new Document(); doc.add(new Field("sort","3",Field.Store.YES,Field.Index.TOKENIZED)); writer.addDocument(doc); doc = new Document(); doc.add(new Field("sort","5",Field.Store.YES,Field.Index.TOKENIZED)); writer.addDocument(doc); doc = new Document(); doc.add(new Field("sort","9",Field.Store.YES,Field.Index.TOKENIZED)); writer.addDocument(doc); doc = new Document(); doc.add(new Field("sort","6",Field.Store.YES,Field.Index.TOKENIZED)); writer.addDocument(doc); doc = new Document(); doc.add(new Field("sort","7",Field.Store.YES,Field.Index.TOKENIZED)); writer.addDocument(doc); writer.close(); } 下面是搜索的例子: public void SearchSort1() throws IOException, ParseException { IndexSearcher indexSearcher = new IndexSearcher("C://indexStore"); QueryParser queryParser = new QueryParser("sort",new StandardAnalyzer()); Query query = queryParser.parse("4"); Hits hits = indexSearcher.search(query); System.out.println("有"+hits.length()+"个结果"); Document doc = hits.doc(0); System.out.println(doc.get("sort")); } public void SearchSort2() throws IOException, ParseException { IndexSearcher indexSearcher = new IndexSearcher("C://indexStore"); Query query = new RangeQuery(new Term("sort","1"),new Term("sort","9"),true); //这个地方前面没有提到,它是用于范围的Query可以看一下帮助文档. Hits hits = indexSearcher.search(query,new Sort(new SortField("sort",new MySortComparatorSource()))); System.out.println("有"+hits.length()+"个结果"); for(int i=0;i< hits.length();i++){ Document doc = hits.doc(i); System.out.println(doc.get("sort")); } } public class MyScoreDocComparator implements ScoreDocComparator { private Integer[]sort; public MyScoreDocComparator(String s,IndexReader reader, String fieldname) throws IOException{ sort = new Integer[reader.maxDoc()]; for(int i = 0;i< reader.maxDoc();i++){ Document doc =reader.document(i); sort[i]=new Integer(doc.get("sort")); } } public int compare(ScoreDoc i, ScoreDoc j){ if(sort[i.doc]>sort[j.doc]) return 1; if(sort[i.doc]< sort[j.doc]) return -1; return 0; } public int sortType(){ return SortField.INT; } public Comparable sortValue(ScoreDoc i){ // TODO 自动生成方法存根 return new Integer(sort[i.doc]); } } public class MySortComparatorSource implements SortComparatorSource { private static final long serialVersionUID = -9189690812107968361L; public ScoreDocComparator newComparator(IndexReader reader, String fieldname) throws IOException{ if(fieldname.equals("sort")) return new MyScoreDocComparator("sort",reader,fieldname); return null; } } SearchSort1()输出的结果没有排序,SearchSort2()就排序了。
2.多域搜索 MultiFieldQueryParser
1.如果想输入关键字而不想关心是在哪个Field里的就可以用MultiFieldQueryParser了。
用它的构造函数即可后面的和一个Field一样。
MultiFieldQueryParser. parse
(String
[] queries, String
[] fields, BooleanClause.Occur
[] flags, Analyzer
analyzer)
第三个参数比较特殊这里也是与以前lucene
1.4.3
不一样的地方,看一个例子就知道了。String[] fields = {"filename", "contents", "description"};
BooleanClause.Occur[] flags = {BooleanClause.Occur.SHOULD,
BooleanClause.Occur.MUST,//在这个Field里必须出现的
BooleanClause.Occur.MUST_NOT};//在这个Field里不能出现
MultiFieldQueryParser.parse("query", fields, flags, analyzer);
2.多索引搜索 MultiSearcher
在构造的时候传进去一个Searcher数组即可
3.过滤器Filter
看个例子:
public void FilterTest() throws IOException, ParseException { IndexWriter indexWriter = new IndexWriter("C://FilterTest",new StandardAnalyzer(),true); Document doc = new Document(); doc.add(new Field("name","程序员之家",Field.Store.YES,Field.Index.TOKENIZED)); indexWriter.addDocument(doc); doc=new Document(); doc.add(new Field("name","程序员杂志",Field.Store.YES,Field.Index.TOKENIZED)); indexWriter.addDocument(doc); indexWriter.close(); Query query = null; Hits hits = null; IndexSearcher indexSearcher = new IndexSearcher("C://FilterTest"); QueryParser queryParser = new QueryParser("name",new StandardAnalyzer()); query = queryParser.parse("程序"); hits = indexSearcher.search(query,new Filter(){ @Override public BitSet bits(IndexReader reader) throws IOException{ BitSet bit = new BitSet(reader.maxDoc()); for(int i=0;i< reader.maxDoc();i++){ if(reader.document(i).get("name").enth("杂志"))//将以“杂志”后缀的过滤掉 continue; bit.set(i);ks } return bit; } }); System.out.println(hits.length()); for(int i=0;i< hits.length();i++){ doc =hits.doc(i); System.out.println(doc.get("name")); } }