lucene的查詢與排序

本文主要記錄一下lucene的另外兩個要點的api使用:查詢與排序。html

查詢

徹底匹配查詢

/**
     * 查找指定field中包含某個關鍵字
     * @throws IOException
     */
    @Test
    public void termQuery() throws IOException {
        String field = "title";
//        String queryStr = "in";
//        String queryStr = "Lucene in Action";
//        String queryStr = "action";
        String queryStr = "lucene";
        Term term = new Term(field,queryStr);
        Query query = new TermQuery(term);
        executeQuery(query);
    }

模糊查詢

/**
     * 查找指定字段中包含與關鍵字類似的文檔
     * 查詢用於匹配與指定項類似的項
     * 編輯距離算法,兩個字符串之間類似度的一個度量方法
     * 用來決定索引文件中的項與指定目標項的類似程度.
     * 取全部相同前綴(前綴長度能夠設定)的詞項作編輯距離
     *
     * 編輯距離其實是代表兩個不一樣的字符串須要通過多少次編輯和變換才能變爲對方。
     * 一般的編輯行爲包括了增長一個檢索項,刪除一個檢索項,修改一個檢索項,
     * 與普通的字符串匹配函數不一樣,模糊搜索裏的編輯距離是以索引項爲單位的。
     *
     * http://www.xinxilong.com/html/?2481.html
     * @throws IOException
     */
    @Test
    public void fuzzyQuery() throws IOException {
        String field = "title";
        String queryStr = "act";// 自動在結尾添加 ~ ,即查詢act~
        Term term = new Term(field,queryStr);
        int maxEdits = 1;  //編輯距離最多不能超過多少
        int prefixLength = 3; //相同的前綴長度
//        Query query = new FuzzyQuery(term,maxEdits,prefixLength);
        Query query = new FuzzyQuery(term,maxEdits);
//        Query query = new FuzzyQuery(term);
        executeQuery(query);
    }

多域查詢

同一個關鍵詞多個字段搜索

/**
     * http://my.oschina.net/MrMichael/blog/220694
     * 同一個關鍵詞多個字段搜索
     * 用MultiFieldQueryParser類實現對同一關鍵詞的跨域搜索
     */
    @Test
    public void multiFieldQueryCrossFields() throws ParseException, IOException {
        String[] fields = new String[]{"title","desc"};
        String queryStr = "good";
        Map<String , Float> boosts = new HashMap<String, Float>();
        //設定它們在搜索結果排序過程當中的權重,權重越高,排名越靠前
        boosts.put("title", 1.0f);
        boosts.put("desc", 0.7f);
        MultiFieldQueryParser parser = new MultiFieldQueryParser(fields, new StandardAnalyzer(),boosts);
        Query query = parser.parse(queryStr);
        executeQuery(query);
    }

使用多個關鍵字及多個field進行查詢

/**
     * 使用多個關鍵字,及多個field進行查詢
     */
    @Test
    public void multiFieldQueryMultiKeyword() throws ParseException, IOException {
        String[] queries = {"good","lucene"};
        String[] fields = {"title","desc"};
        BooleanClause.Occur[] clauses = {BooleanClause.Occur.SHOULD, BooleanClause.Occur.SHOULD};
        Query query = MultiFieldQueryParser.parse(queries,fields,clauses,new StandardAnalyzer());
        executeQuery(query);
    }

通配符查詢

/**
     * 通配符查詢
     * 星號*:表明0個或多個字母
     * 問號?:表明0個或1個字母
     */
    @Test
    public void wildcardQuery() throws IOException {
        String field = "title";
//        String queryStr = "*pute?";
        String queryStr = "act*";
        Term term = new Term(field,queryStr);
        Query query = new WildcardQuery(term);
        executeQuery(query);
    }

前綴查詢

/**
     * 前綴查詢
     * 自動在關鍵詞末尾添加*
     */
    @Test
    public void prefixQuery() throws IOException {
        String field = "title";
        String queryStr = "act"; //act*
        Term term = new Term(field,queryStr);
        Query query = new PrefixQuery(term);
        executeQuery(query);
    }

短語查詢

/**
     * http://blog.csdn.net/rick_123/article/details/6708527
     * 短語查詢,對關鍵詞加引號,經過位置移動來匹配
     * slop的概念:slop是指兩個項的位置之間容許的最大間隔距離
     * 例如:slop設置爲1,則 quick brown fox 能夠匹配 quick fox
     */
    @Test
    public void phraseQuery() throws IOException {
        Query query = new PhraseQuery.Builder()
                .setSlop(3)
                .add(new Term("title", "computer"))
                .add(new Term("title","art"))
                .build();
        executeQuery(query);
    }

跨度查詢

/**
     * http://callan.iteye.com/blog/154251
     * 跨度查詢,用於查詢多個詞的時候考慮幾個詞在文檔中的匹配位置
     * 與phraseQuery和multiFieldQuery很類似,都是經過位置限制匹配
     * 可是spanQuery更加靈活
     *
     * SpanQuery包括如下幾種:
     * SpanTermQuery:詞距查詢的基礎,結果和TermQuery類似,只不過是增長了查詢結果中單詞的距離信息。
     * SpanFirstQuery:在指定距離能夠找到第一個單詞的查詢。
     * SpanNearQuery:查詢的幾個語句之間保持者必定的距離。
     * SpanOrQuery:同時查詢幾個詞句查詢。
     * SpanNotQuery:從一個詞距查詢結果中,去除一個詞距查詢。
     */
    @Test
    public void spanQuery() throws IOException {
        SpanTermQuery query = new SpanTermQuery(new Term("title","art"));
        executeQuery(query);
    }

    /**
     * 第一次出如今指定位置
     * @throws IOException
     */
    @Test
    public void spanFirstQuery() throws IOException {
        SpanTermQuery query = new SpanTermQuery(new Term("title","art"));
        SpanFirstQuery spanFirstQuery =new SpanFirstQuery(query,2); //出如今第2個位置
        executeQuery(spanFirstQuery);
    }

    /**
     * SpanNearQuery中將SpanTermQuery對象做爲SpanQuery對象使用的效果,與使用PharseQuery的效果很是類似。
     * 最大的區別是:在SpanNearQuery的構造函數中的第三個參數爲inOrder標誌,設置這個標誌爲true,項添加的順序和其文檔中出現的順序相同
     */
    @Test
    public void spanNearQuery() throws IOException {
        SpanTermQuery queryScience = new SpanTermQuery(new Term("title","science"));
        SpanTermQuery queryArt = new SpanTermQuery(new Term("title","art"));
        SpanQuery[] queries = new SpanQuery[]{queryScience,queryArt};
        int slop = 2;//science 與 art兩個詞間隔在2之內
        boolean inOrder = false;//不須要按數組中的順序出如今文檔中
        SpanNearQuery query = new SpanNearQuery(queries,slop,inOrder);
        executeQuery(query);
    }

    @Test
    public void spanOrQuery() throws IOException {
        SpanTermQuery queryScience = new SpanTermQuery(new Term("title","science"));
        SpanTermQuery queryArt = new SpanTermQuery(new Term("title","art"));
        SpanQuery[] queries = new SpanQuery[]{queryScience,queryArt};
        int slop = 2;//science 與 art兩個詞間隔在2之內
        boolean inOrder = false;//不須要按數組中的順序出如今文檔中
        SpanNearQuery spanNearQuery = new SpanNearQuery(queries,slop,inOrder);

        SpanTermQuery queryComputer = new SpanTermQuery(new Term("title","lucene"));

        SpanOrQuery query = new SpanOrQuery(new SpanQuery[]{spanNearQuery,queryComputer});
        executeQuery(query);
    }

組合查詢

/**
     * 組合查詢
     * MUST與MUST組合表示並集
     * MUST與MUST_NOT表示包含與不包含
     * MUST_NOT與MUST_NOT組合沒有意義
     * SHOULD與SHOULD組合表示或
     * SHOULD與MUST表示MUST,其中SHOULD沒有任何價值
     * SHOULD與MUST_NOT至關於MUST與MUST_NOT表示包含與不包含
     */
    @Test
    public void booleanQuery() throws IOException {
        TermQuery queryComputerInTitle = new TermQuery(new Term("title","computer"));
        TermQuery queryGoodInDesc = new TermQuery(new Term("desc","good"));

        BooleanQuery booleanQuery = new BooleanQuery.Builder()
                .add(queryComputerInTitle,BooleanClause.Occur.SHOULD)
                .add(queryGoodInDesc,BooleanClause.Occur.SHOULD)
                .setMinimumNumberShouldMatch(1)
                .build();
        executeQuery(booleanQuery);
    }

排序

根據域值排序

/**
     * 按指定字段排序
     * @throws IOException
     * @throws ParseException
     */
    @Test
    public void sortByField() throws IOException, ParseException {
        //Sort using term values as encoded Integers.  Sort values are Integer and lower values are at the front.
        boolean isReverse = false;
        SortField sortField = new SortField("title", SortField.Type.STRING,isReverse);
        Query query = new TermQuery(new Term("title","lucene"));
        Sort sort = new Sort(sortField);
        executeQuery(query, sort);
    }

根據索引順序查詢

/**
     * 按索引順序排序
     * @throws IOException
     */
    @Test
    public void sortByIndexOrder() throws IOException {
        Query query = new TermQuery(new Term("title","lucene"));
        executeQuery(query,Sort.INDEXORDER);
    }

根據相關性排序

/**
     * 按文檔的得分排序
     * @throws IOException
     */
    @Test
    public void sortByRelevance() throws IOException {
        TermQuery queryComputerInTitle = new TermQuery(new Term("title","computer"));
        TermQuery queryGoodInDesc = new TermQuery(new Term("desc","good"));

        BooleanQuery query = new BooleanQuery.Builder()
                .add(queryComputerInTitle,BooleanClause.Occur.SHOULD)
                .add(queryGoodInDesc,BooleanClause.Occur.SHOULD)
                .setMinimumNumberShouldMatch(1)
                .build();
        executeQuery(query,Sort.RELEVANCE);
    }

本工程githubjava

參考

相關文章
相關標籤/搜索