有关Lucene的问题(1):为什么能搜的到“中华 AND 共和国”却搜不到“中华共和国”?

字体大小: 中小 标准 ->行高大小: 标准

问题:

使用中科院的中文分词对“中华人民共和国” 进行索引,它被分词为"中华", "人民", "共和国",用“人民共和国”进行搜索,可以搜到,而搜索"中华共和国"却搜索不到,用“中华 AND 共和国”却可以搜出来,为什么?

回答:

我下载了http://ictclas.org/Download.html中科院的词做了简单的分析,如果索引的时候“中华人民共和国”被分成了“中华”“人民”“共和国”,而搜索的时候,搜“中华共和国”,则被分为了“中华 共和国”,然而构建Query Parser构建Query Object的时候,却将它构建成了PhraseQuery—— contents:"中华 共和国" ,而非BooleanQuery——contents:中华 contents:共和国,根据PhraseQuery的解释,它有一个参数slop来表示两个词之间的距离,默认为0,也即只有在文档不但包含“中华”而且包含“共和国”并且二者相邻的时候才能返回。这就是为什么“人民共和国”可以搜出来(它构建的是PhraseQuery,但是相邻),“中华 AND 共和国”能搜索出来(它构建的是BooleanQuery),而“中华共和国”搜不出来的原因(它构建的是PhraseQuery,但不相邻)。

尝试解析Query query = parser.parse("\"中华共和国\"~1")

或者用API设置Slop为1,就能搜索出结果了。

Query query = parser.parse("中华共和国"); 
PhraseQuery pquery = (PhraseQuery)query; 
pquery.setSlop(1);

实例:

Analyzer ca = new ChineseAnalyzer();

QueryParser parser = new QueryParser(field, ca);

Query query1 = parser.parse("人民共和国");

System.out.println("Searching for: " + query1.toString(field));

查询对象为:

query1    PhraseQuery  (id=39)    
    boost    1.0    
    field    "contents"    
    maxPosition    1    
    positions    ArrayList<E>  (id=45)    
    slop    0    
    terms    ArrayList<E>  (id=49)    
        elementData    Object[4]  (id=74)    
            [0]    Term  (id=76)    
                field    "contents"    
                text    "人民"    
            [1]    Term  (id=77)    
                field    "contents"    
                text    "共和国" 

相当于查询语句:

Searching for: "人民 共和国"

Query query2 = parser.parse("中华 AND 共和国");

System.out.println("Searching for: " + query2.toString(field));

查询对象为:

query2    BooleanQuery  (id=43)    
    boost    1.0    
    clauses    ArrayList<E>  (id=56)    
        elementData    Object[10]  (id=57)    
            [0]    BooleanClause  (id=59)    
                occur    BooleanClause$Occur  (id=62)    
                    name    "MUST"    
                query    TermQuery  (id=65)    
                    boost    1.0    
                    term    Term  (id=70)    
                        field    "contents"    
                        text    "中华"    
            [1]    BooleanClause  (id=61)    
                occur    BooleanClause$Occur  (id=62)    
                    name    "MUST"    
                query    TermQuery  (id=64)    
                    boost    1.0    
                    term    Term  (id=68)    
                        field    "contents"    
                        text    "共和国"

相当于查询语句:

Searching for: +中华 +共和国

Query query3 = parser.parse("\"中华共和国\"~1");

System.out.println("Searching for: " + query3.toString(field));

查询对象为:

query3    PhraseQuery  (id=54)    
    boost    1.0    
    field    "contents"    
    maxPosition    1    
    positions    ArrayList<E>  (id=93)    
    slop    1    
    terms    ArrayList<E>  (id=94)    
        elementData    Object[4]  (id=96)    
            [0]    Term  (id=97)    
                field    "contents"    
                text    "中华"    
            [1]    Term  (id=98)    
                field    "contents"    
                text    "共和国"

相当于查询语句:

Searching for: "中华 共和国"~1

Query query4 = parser.parse("中华共和国");

PhraseQuery pquery = (PhraseQuery)query4;

pquery.setSlop(1);

System.out.println("Searching for: " + query4.toString(field));

查询对象为:

query4    PhraseQuery  (id=55)    
    boost    1.0    
    field    "contents"    
    maxPosition    1    
    positions    ArrayList<E>  (id=102)    
    slop    1    
    terms    ArrayList<E>  (id=103)    
        elementData    Object[4]  (id=105)    
            [0]    Term  (id=107)    
                field    "contents"    
                text    "中华"    
            [1]    Term  (id=108)    
                field    "contents"    
                text    "共和国"

相当于查询语句:

Searching for: "中华 共和国"~1

此文章由 http://www.ositren.com 收集整理 ,地址为: http://www.ositren.com/htmls/69408.html