Lucene 排序 Sort與SortField

木子小僧發表於2016-12-27

 在sql語句中,有升序和降序排列。在Lucene中,同樣也有。

Sort裡的屬性 SortField裡的屬性 含義
Sort.INDEXORDER SortField.FIELD_DOC 按照索引的順序進行排序
Sort.RELEVANCE SortField.FIELD_SCORE 按照關聯性評分進行排序
=========SortField類============
//field是排序欄位type是排序型別
public SortField(String field, Type type);
//field是排序欄位type是排序型別reverse是指定升序還是降序
//reverse 為true是降序  false為升序
public SortField(String field, Type type, boolean reverse)

=========Sort類============
public Sort();//Sort物件構造方法預設是按文件評分排序
public Sort(SortField field);//排序的一個SortField
public Sort(SortField... fields)//排序的多個SortField可以傳入一個陣列

 

前提,建立索引:

 1 import java.io.File;
 2 import java.io.FileReader;
 3 import java.io.IOException;
 4 import java.nio.file.Paths;
 5 import java.util.Random;
 6 
 7 import org.apache.lucene.analysis.standard.StandardAnalyzer;
 8 import org.apache.lucene.document.Document;
 9 import org.apache.lucene.document.Field;
10 import org.apache.lucene.document.IntField;
11 import org.apache.lucene.document.LongField;
12 import org.apache.lucene.document.NumericDocValuesField;
13 import org.apache.lucene.index.IndexWriter;
14 import org.apache.lucene.index.IndexWriterConfig;
15 import org.apache.lucene.store.Directory;
16 import org.apache.lucene.store.FSDirectory;
17 
18 public class FileIndexUtils {
19     private static Directory directory = null;
20     static{
21         try {
22             directory = FSDirectory.open(Paths.get("D://lucene//document"));
23         } catch (Exception e) {
24             // TODO: handle exception
25             e.printStackTrace();
26         }
27     }
28     public static Directory getDirectory(){
29         return directory;
30     }
31     /**
32      * 建立索引
33      * @param hasNew
34      */
35     @SuppressWarnings("deprecation")
36     public static void createIndex(boolean hasNew){
37         IndexWriter writer = null;
38         try {
39             writer = new IndexWriter(directory, new IndexWriterConfig(new StandardAnalyzer()));
40             if(hasNew){
41                 writer.deleteAll();
42             }
43         
44             Document document = null;
45             int index = 0;
46             //隨機數,為排序數字
47             Random random = new Random();
48             //為原始檔建立索引
49             File file = new File("D://text");
50             for(File f:file.listFiles()){
51                 int score = random.nextInt();
52                 document = new Document();
53                 document.add(new Field("id",String.valueOf(index++), Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
54                 document.add(new Field("content",new FileReader(f)));
55                 document.add(new Field("fileName",f.getName(),Field.Store.YES,Field.Index.NOT_ANALYZED));
56                 document.add(new Field("path",f.getPath(),Field.Store.YES,Field.Index.NOT_ANALYZED));
57                 document.add(new IntField("score",score,Field.Store.YES));
58                 document.add(new NumericDocValuesField("size",(long)f.length()));
59                 document.add(new LongField("size", f.length(), Field.Store.YES));
60                 document.add(new IntField("date",(int) f.lastModified(),Field.Store.YES));
61                 writer.addDocument(document);
62             }        
63         } catch (Exception e) {
64             // TODO: handle exception
65             e.printStackTrace();
66         }finally{
67             if(writer!=null){
68                 try {
69                     writer.close();
70                 } catch (IOException e) {
71                     // TODO Auto-generated catch block
72                     e.printStackTrace();
73                 }
74             }
75         }
76     }
77 }
View Code

 

一,Sort排序

getSearcher()

 1 private static IndexReader reader = null;
 2     static{
 3         try {
 4             reader = DirectoryReader.open(FileIndexUtils.getDirectory());
 5         } catch (Exception e) {
 6             // TODO: handle exception
 7             e.printStackTrace();
 8         }
 9     }
10     
11     public IndexSearcher getSearcher(){
12         try {
13             if(reader == null){
14                 reader = DirectoryReader.open(FileIndexUtils.getDirectory());
15             }else{
16                 IndexReader tr = DirectoryReader.openIfChanged((DirectoryReader) reader);
17                 if(tr!=null) {
18                     reader.close();
19                     reader = tr;
20                 }
21             }
22             return new IndexSearcher(reader);
23         } catch (Exception e) {
24             // TODO: handle exception
25             e.printStackTrace();
26         }
27         return null;
28     }
View Code

 

   /**
     * 排序Sort
     * @param queryStr
     * @param sort
     */
    public void searcherBySort(String queryStr,Sort sort) {
        try {
            IndexSearcher searcher = getSearcher();
            QueryParser parser = new QueryParser("content",new StandardAnalyzer());
            Query query = parser.parse(queryStr);
            TopDocs tds = null;
            if(sort!=null)
                tds = searcher.search(query, 50, sort);
            else {
                tds = searcher.search(query, 50);
            }
            for(ScoreDoc sd:tds.scoreDocs) {
                Document d = searcher.doc(sd.doc);
                System.out.println(sd.doc+":("+sd.score+")" +
                        "["+d.get("fileName")+"【"+d.get("path")+"】---"+d.get("score")+"--->"+
                        Integer.valueOf(d.get("size"))/1024+"-----");
            }
            
        } catch (Exception e) {
            e.printStackTrace();
        } 
    }

測試:

    @Test
    public void test01(){
        st.searcherBySort("select",Sort.RELEVANCE);
        System.out.println("------------");
        st.searcherBySort("select",null);
    }

二、SortField

 

/**
     * 排序SortField
     * @param sortField
     * @param reverse
     */
    public void searcherBySortField(String filename,boolean reverse){
        try {
            IndexSearcher searcher = getSearcher();
            SortField sortField = new SortField(filename,SortField.Type.LONG,reverse);
            Sort sort = new Sort(sortField);
            
            TopDocs tds = searcher.search(new MatchAllDocsQuery(),100,sort);
            for(ScoreDoc sd:tds.scoreDocs){
                Document d = searcher.doc(sd.doc);
                System.out.println("["+d.get("fileName")+"]【"+d.get("path")+"】---score:"+d.get("score")+"--->"+"size:"+d.get("size"));
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally{
            try {
                if(reader!=null){
                    reader.close();
                }
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}

測試:

    @Test
    public void test02(){
        st.searcherBySortField("size", false);
        System.out.println("------------");
    }

size根據大小排序。

相關文章