`

有关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
分享到:
评论
3 楼 parabellum_sky 2010-07-14  
可能就是把中华共和国当作一个自定义词组来存储了。
一旦搜索引擎碰到这个词,就不会去给它分词了。
2 楼 johnsoncr 2010-04-15  
LZ分析得很好
1 楼 naughty610 2010-02-07  
是因为辞典中含有中华共和国这个词。
这样在建立索引的时候,仅仅存储了这么一个词,而不是“中华”和“共和国”这两个词。
不知道回答的对不对,等待高人

相关推荐

    Lucene_3.0_原理与代码分析

    8. **IndexReader(索引读取器)**:用于读取索引,但不能修改索引。 9. **Query(查询)**:用户输入的查询语句,可以是简单的关键词或复杂的布尔表达式。 10. **ScoreDoc(评分文档)**:包含匹配文档的信息及其...

    Lucene 3.0 原理与代码分析

    - **为何能搜到“中华 AND 共和国”却搜不到“中华共和国”**:这是因为默认情况下,Lucene会对查询词进行AND操作,如果两个词不在同一个Posting List中,则无法匹配。 - **Stemming和Lemmatization**:Stemming是...

    Lucene+3.0+原理与代码分析完整版

    1. **“中华AND共和国”与“中华共和国”的区别**:由于Lucene默认使用标准分词器,它会将连续的字母数字序列视为一个词条,因此“中华AND共和国”会被分词为“中华”、“AND”和“共和国”,而“中华共和国”则被...

    lucene原理与代码分析完整版

    - 为什么能搜到特定组合关键词(如“中华AND共和国”),却搜不到另一个组合(如“中华共和国”)? - Stemming和Lemmatization的区别及其在全文检索中的应用。 - 向量空间模型与Lucene的打分机制之间的联系。 - ...

    Lucene 3.0 原理与代码分析完整版

    例如,有时可能会遇到“中华共和国”能够搜索到,而“中华共和国”却搜索不到的情况。这通常与Lucene的查询解析和索引过程中的词项处理方式有关。另外,stemming(词干提取)和lemmatization(词形还原)是两种不同...

    Lucene 2 教程

    每个文件的内容可以自定义,例如 "1.txt" 内容可以包含“中华人民共和国”、“全国人民”、“2006年”。 接下来,将 Lucene 的库文件添加到你的项目类路径(classpath)中。然后,你可以使用以下 Java 代码来创建...

    lecene原理与代码分析

    在实际应用中,用户可能会遇到各种问题,例如为何能搜索到“中华AND共和国”却搜不到“中华共和国”,这涉及到Lucene的查询解析和处理机制。此外,Lucene的分词策略(stemming和lemmatization)和文档打分机制也会...

    IK中文分词器详细介绍

    例如,对于输入“中华人民共和国成立了”,首先识别出“中华人民共和国”和“成立了”,然后再分别对这两个词汇进行切分,最终得到一系列词汇的集合。 3. **递归处理**: 对于每个切分出的词汇,算法都会检查是否...

Global site tag (gtag.js) - Google Analytics