Lucene的Query類介紹


把Lucene的查詢當成sql的查詢,也許會籠統的明白些query的真相了。

查詢分為大致兩類,1:精准查詢。2,模糊查詢。

創建測試數據。

private Directory directory;
    private IndexReader reader;
    private String[] ids = {"1","2","3","4","5","6"};
    private String[] emails = {"aa@itat.org","bb@itat.org","cc@cc.org","dd@sina.org","ee@zttc.edu","ff@itat.org"};
    private String[] contents = {
            "welcome to visited the space,I like book",
            "hello boy, I like pingpeng ball",
            "my name is cc I like game",
            "I like football",
            "I like football and I like basketball too",
            "I like movie and swim"
    };
    private int[] attachs = {2,3,1,4,5,5};
    private String[] names = {"zhangsan","lisi","john","jetty","lisi","jake"};

先建立索引。

 

 1 private Map<String,Float> scores = new HashMap<String,Float>();
 2     
 3 public SearchUtil(){
 4     try {
 5         directory = FSDirectory.open(Paths.get("D://lucene//index"));
 6         scores.put("itat.org", 1.5f);
 7         scores.put("cc.org", 2.0f);
 8     } catch (IOException e) {
 9         // TODO Auto-generated catch block
10         e.printStackTrace();
11     }
12 }
13 /**
14  * 創建索引
15  */
16 @SuppressWarnings("deprecation")
17 public void index(){
18     IndexWriter writer = null;
19     try {
20         directory = FSDirectory.open(Paths.get("D://lucene//index"));
21         writer = getWriter();
22         Document doc = null;
23         for(int i=0;i<ids.length;i++){
24             doc = new Document();
25             doc.add(new Field("id", ids[i], Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
26             doc.add(new Field("name", names[i], Field.Store.YES,Field.Index.NOT_ANALYZED_NO_NORMS));
27             doc.add(new Field("content", contents[i], Field.Store.NO,Field.Index.ANALYZED));
28             //存儲數字
29             doc.add(new IntField("attach", attachs[i],  Field.Store.YES));
30             
31             // 加權操作
32             TextField field = new TextField("email", emails[i], Field.Store.YES);
33             String et = emails[i].substring(emails[i].lastIndexOf("@")+1);
34             if (scores.containsKey(et)) {
35                 field.setBoost(scores.get(et));
36             }
37             doc.add(field);
38             // 添加文檔
39             writer.addDocument(doc);
40         }
41     } catch (Exception e) {
42         // TODO: handle exception
43         e.printStackTrace();
44     }finally{
45         try {
46             writer.close();
47         } catch (IOException e) {
48             // TODO Auto-generated catch block
49             e.printStackTrace();
50         }
51     }
52 }

 

 索引建立完畢。

構造方法。

/**
     * getSearcher
     * @return
     */
    public IndexSearcher getSearcher(){
        try {
            directory = FSDirectory.open(Paths.get("D://lucene//index"));
            if(reader==null){
                reader = DirectoryReader.open(directory);
            }else{
                reader.close();
            }
            return new IndexSearcher(reader);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

一、精准匹配。

1,精准查詢

就是查什么給什么。

 1 /**
 2      * 精准匹配
 3      */
 4     public void search(String searchField,String field){
 5         // 得到讀取索引文件的路徑
 6         IndexReader reader = null;
 7         try {
 8             directory = FSDirectory.open(Paths.get("D://lucene//index"));
 9             reader = DirectoryReader.open(directory);
10             IndexSearcher searcher = new IndexSearcher(reader);
11             // 運用term來查找
12             Term t = new Term(searchField, field);
13             Query q = new TermQuery(t);
14             // 獲得查詢的hits
15             TopDocs hits = searcher.search(q, 10);
16             // 顯示結果
17             System.out.println("匹配 '" + q + "',總共查詢到" + hits.totalHits + "個文檔");
18             for (ScoreDoc scoreDoc : hits.scoreDocs){
19                 Document doc = searcher.doc(scoreDoc.doc);
20                 System.out.println("id:"+doc.get("id")+":"+doc.get("name")+",email:"+doc.get("email"));
21             }
22             
23         } catch (IOException e) {
24             // TODO Auto-generated catch block
25             e.printStackTrace();
26         }finally{
27             try {
28                 reader.close();
29             } catch (IOException e) {
30                 // TODO Auto-generated catch block
31                 e.printStackTrace();
32             }
33         }
34     }

 

2,區間查詢。

/**
     * between
     * @param field
     * @param start
     * @param end
     * @param num
     */
    public void searchByTermRange(String field,String start,String end,int num) {
        try {
            IndexSearcher searcher = getSearcher();
            BytesRef lowerTerm = new BytesRef(start.getBytes()) ;
            BytesRef upperTerm = new BytesRef(end.getBytes()) ;
            
            Query query = new TermRangeQuery(field, lowerTerm , upperTerm, true, true);
            TopDocs tds = searcher.search(query, num);
            
            System.out.println("一共查詢了:"+tds.totalHits);
            for(ScoreDoc sd:tds.scoreDocs) {
                Document doc = searcher.doc(sd.doc);
                System.out.println(doc.get("id")+"---->"+
                        doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
                        doc.get("attach"));
            }
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 

3、匹配其索引開始以指定的字符串的文檔

 1 /**
 2      * 匹配其索引開始以指定的字符串的文檔
 3      * @param field
 4      * @param value
 5      * @param num
 6      */
 7     public void searchByPrefix(String field,String value,int num) {
 8         try {
 9             IndexSearcher searcher = getSearcher();
10             Query query = new PrefixQuery(new Term(field,value));
11             TopDocs tds = searcher.search(query, num);
12             System.out.println("一共查到:"+tds.totalHits);
13             for(ScoreDoc scoreDoc:tds.scoreDocs){
14                 Document doc = searcher.doc(scoreDoc.doc);
15                 System.out.println(doc.get("id")+"---->"+
16                         doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
17                         doc.get("attach"));
18             }
19         } catch (Exception e) {
20             e.printStackTrace();
21         }
22     }

4、數字搜索

/**
     * 數字搜索
     * @param field
     * @param start
     * @param end
     * @param num
     */
    public void searchByNums(String field,int start,int end,int num){
        try {
            IndexSearcher searcher = getSearcher();
            Query query =   NumericRangeQuery.newIntRange(field, start, end, true, true);
            TopDocs tds = searcher.search(query, num);
            System.out.println("一共查到:"+tds.totalHits);
            for(ScoreDoc scoreDoc:tds.scoreDocs){
                Document doc = searcher.doc(scoreDoc.doc);
                System.out.println(doc.get("id")+"---->"+
                        doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
                        doc.get("attach"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

二、模糊匹配

/**
     * 通配符
     * @param field
     * @param value
     * @param num
     */
    public void searchByWildcard(String field,String value,int num){
        try {
            IndexSearcher searcher = getSearcher();
            WildcardQuery query = new WildcardQuery(new Term(field,value));
            TopDocs tds = searcher.search(query, num);
            System.out.println("一共查到:"+tds.totalHits);
            for(ScoreDoc scoreDoc:tds.scoreDocs){
                Document doc = searcher.doc(scoreDoc.doc);
                System.out.println(doc.get("id")+"---->"+
                        doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
                        doc.get("attach"));
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
    /**
     * BooleanQuery可以連接多個子查詢
     * Occur.MUST表示必須出現
     * Occur.SHOULD表示可以出現
     * Occur.MUSE_NOT表示不能出現
     * @param field
     * @param value
     * @param num
     */
    @SuppressWarnings("deprecation")
    public void searchByBoolean(String[] field,String[] value,int num){
        try {
            if(field.length!=value.length){
                System.out.println("field的長度需要與value的長度相等!");
                System.exit(0);
            }
            IndexSearcher searcher = getSearcher();
            BooleanQuery query = null;
            TopDocs tds = null;
            for(int i = 0;i<field.length;i++){
                query = new BooleanQuery();
                query.add(new TermQuery(new Term(field[i],value[i])),Occur.SHOULD);
                tds = searcher.search(query, num);
            }
            System.out.println("一共查詢:"+tds.totalHits);
            for(ScoreDoc doc:tds.scoreDocs){
                Document document = searcher.doc(doc.doc);
                System.out.println(document.get("id")+"---->"+
                        document.get("name")+"["+document.get("email")+"]-->"+document.get("id")+","+
                        document.get("attach"));
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
    public void searchByPhrase(int num){
        try {
            IndexSearcher searcher = getSearcher();
            PhraseQuery query = new PhraseQuery();
            query.setSlop(3);
            query.add(new Term("content","like"));
//            //第一個Term
            query.add(new Term("content","football"));
            TopDocs tds = searcher.search(query, num);
            System.out.println("一共查詢了:"+tds.totalHits);
            for(ScoreDoc sd:tds.scoreDocs) {
                Document doc = searcher.doc(sd.doc);
                System.out.println(doc.get("id")+"---->"+
                        doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
                        doc.get("attach"));
            }
        } catch (Exception e) {
            // TODO: handle exception
            e.printStackTrace();
        }
    }
    /**
     * 相似度匹配查詢
     * @param num
     */
    public void searchByFuzzy(int num) {
        try {
            IndexSearcher searcher = getSearcher();
            FuzzyQuery query = new FuzzyQuery(new Term("name","jake")); 
            TopDocs tds = searcher.search(query, num);
            System.out.println("一共查詢了:"+tds.totalHits);
            for(ScoreDoc sd:tds.scoreDocs) {
                Document doc = searcher.doc(sd.doc);
                System.out.println(doc.get("id")+"---->"+
                        doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
                        doc.get("attach")+","+doc.get("date"));
            }
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public void searchByQueryParse(Query query,int num) {
        try {
            IndexSearcher searcher = getSearcher();
            TopDocs tds = searcher.search(query, num);
            System.out.println("一共查詢了:"+tds.totalHits);
            for(ScoreDoc sd:tds.scoreDocs) {
                Document doc = searcher.doc(sd.doc);
                System.out.println(doc.get("id")+"---->"+
                        doc.get("name")+"["+doc.get("email")+"]-->"+doc.get("id")+","+
                        doc.get("attach")+","+doc.get("date")+"=="+sd.score);
            }
        } catch (CorruptIndexException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM