TermQuery不会返回已知的搜索词,但WildcardQuery会这样做

时间:2012-02-24 12:53:08

标签: lucene.net sitecore sitecore6 lucene

希望有足够洞察Lucene内部运作的人可能能够指出我正确的方向=)

我将跳过大部分周围的相关代码,并切入正确的追逐。我有一个Lucene索引,我将以下字段添加到索引中(变量由其文字值替换):

document.Add( new Field("Typenummer", "E5CEB501A244410EB1FFC4761F79E7B7", 
                        Field.Store.YES , Field.Index.UN_TOKENIZED));

稍后,当我搜索我的索引(使用其他类型的查询)时,我能够验证此字段确实出现在我的索引中 - 比如循环遍历Document.GetFields()返回的所有Fields

Field: Typenummer, Value: E5CEB501A244410EB1FFC4761F79E7B7

到目前为止很好: - )

现在真正的问题是 - 为什么我不能使用TermQuery来搜索这个值并实际得到结果。

此代码产生0次点击:

// Returns 0 hits
bq.Add( new TermQuery( new Term( "Typenummer", 
        "E5CEB501A244410EB1FFC4761F79E7B7" ) ), BooleanClause.Occur.MUST );

但如果我将其切换为WildcardQuery(没有通配符),我会得到我期望的1次点击。

// returns the 1 hit I expect
bq.Add( new WildcardQuery( new Term( "Typenummer", 
        "E5CEB501A244410EB1FFC4761F79E7B7" ) ), BooleanClause.Occur.MUST );

我已经检查了字段长度,我已经检查过我使用的是同一个分析仪等等,我仍然在方块1上,为什么会这样。

有人能指出我应该朝的方向吗?

1 个答案:

答案 0 :(得分:8)

我终于弄清楚发生了什么。我正在扩展这个问题的标签,因为它让我感到意外,实际上证明了CMS存在这个特殊问题的问题。总之,问题归结为:

  1. 该字段存储在UN_TOKENIZED中,这意味着Lucene会将其存储为“原样”
  2. 我粘贴的BooleanQuery片段被发送到PreparedQuery包装器内的Sitecore SearchManager
  3. 我对此的期望是,我的查询(已经准备好了)将不会改变为Lucene API
  4. 原来我错了。它传递一个RewriteQuery方法,该方法按原样复制我的整个嵌套查询集,但有一个例外 - 所有Term参数都通过LowercaseStrategy()传递
  5. 当我索引大写术语(UN_TOKENIZED)时,Sitecore将我的PreparedQuery更改为小写 - 返回0结果
  6. 我不打算开始讨论这是“按设计”还是“设计缺陷”Lucene Wrapper API的实现 - 我只是注意到在使用PreparedQuery重载时重写我的查询是...我...意外; - )

    进一步的教导;将字段存储为TOKENIZED也将消除此问题,因为默认情况下StandardAnalyzer会将所有标记小写。