有关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
posted @ 2010-02-06 13:04  刘超觉先  阅读(...)  评论(... 编辑 收藏