Solr 4,
上一篇,介绍了 Solr 的查询。
搜索的难点
当一位顾客想要看一本关于 buying a home 的书,假设数据是存储在关系型数据库中的。
我们也许会写这么一条搜索语句:
SELECT * FROM Books
WHERE Name = 'buying a new home';好吧,也许返回的结果是 0 条,但数据库中存在着类似 the guide of buying your house 之类的书名。
理所当然,我们把查询语句改为:
SELECT * FROM Books
WHERE Name LIKE '%buying%'
OR Name LIKE '%a%'
OR Name LIKE '%home%';但这样一来,我们也许把 how to raise a dog 这样的书名也给检索出来了。
看看改善的方案,以及还有其他什么问题:
1. 我们可以将 a the 这种和搜索无关的词过滤掉。
2. 当用户输入 buying 的时候,或许他也希望看到和 buy 或者 purchase 有关的书籍。(各种形式,同义词)
3. 查询结果只是按存储顺序返回,没有主次关系。
4. 遍历查询的速度也许令人担忧。
为此,Solr,也就是 Lucene 使用了许多方法来改善这些,比如各种各样的分词器,比如倒序索引,比如评分机制等。(有些之前的文章提到过)
BooleanQuery
在 Lucene 有一个类 BooleanQuery 就把两个查询做个布尔合并。
通过 QueryParse,只需要简单的用 AND OR NOT 和 (),就可以写出复杂的查询语句了。
这在 Solr 中也是一样的。
PhraseQuery
这个我之前学 Lucene 忽略了,这里提一下。
这是短语查询,用双引号包括即可,比如 “Enterprise Search”。
这和搜索 Enterprise Search 的返回结果是不同的。
分词器将短语分割为 “Enterprise” 和 "Search" 时,同时也记录了他们的位置,比如【0】【1】。
就确保了两个单词的顺序关系,且他们当中不存在另一个单词。
FuzzyQuery
模糊查询,需要用到通配符 * 和 ?。
有时模糊查询是一个很耗时的操作,需要谨慎。
RangeQuery
区域查询,形式多种多样。
时间段:[2012-02-01T00:00.0Z TO 2012-08-02T00:00.0Z]。
数字段:[18 TO 21] {18 TO 21]
文本段:[boat TO boulder]
文本的查询可能不太常见,应该是逐位转化为 char 再比较,而 char 也是整数的一种。
还有一种用于容错,允许用户拼写错误的查询,就叫容错查询吧,忽略。