solr

常用查询参数

q - 查询字符串,必须的。
fl - 指定返回那些字段内容,用逗号或空格分隔多个。
start - 返回第一条记录在完整找到结果中的偏移位置,0开始,一般分页用。
rows - 指定返回结果最多有多少条记录,配合start来实现分页。
sort - 排序,格式:sort=<field name>+<desc|asc>[,<field name>+<desc|asc>]… 。示例:(inStock desc, price asc)表示先 “inStock” 降序, 再 “price” 升序,默认是相关性降序。
wt - (writer type)指定输出格式,可以有 xml, json, php, phps, 后面 solr 1.3增加的,要用通知我们,因为默认没有打开。
fq - (filter query)过虑查询,作用:在q查询符合结果中同时是fq查询符合的,例如:q=mm&fq=date_time:[20081001 TO 20091031],找关键字mm,并且date_time是20081001到20091031之间的。官方文档:http://wiki.apache.org/solr/CommonQueryParameters#head-6522ef80f22d0e50d2f12ec487758577506d6002
不常用

q.op - 覆盖schema.xml的defaultOperator(有空格时用"AND"还是用"OR"操作逻辑),一般默认指定
df - 默认的查询字段,一般默认指定
qt - (query type)指定那个类型来处理查询请求,一般不用指定,默认是standard。
其它

indent - 返回的结果是否缩进,默认关闭,用 indent=true|on 开启,一般调试json,php,phps,ruby输出才有必要用这个参数。
version - 查询语法的版本,建议不使用它,由服务器指定默认值。

===============================

solr 基础知识

一、 醒目显示的查询参数 1. q Solr 中用来搜索的查询。有关该语法的完整描述,请参阅 参考资料 中的 “Lucene QueryParser Syntax”。可以通过追加一个分号和已索引且未进行断词的字段(下面会进行解释)的名称来包含排序信息。默认的排序是 score desc,指按记分降序排序。 q=myField:Java AND otherField:developerWorks; date asc
此查询搜索指定的两个字段并根据一个日期字段对结果进行排序。

2. start 将初始偏移量指定到结果集中。可用于对结果进行分页。默认值为 0。 start=15
返回从第 15 个结果开始的结果。

3. rows 返回文档的最大数目。默认值为 10。 rows=25

4. fq 提供一个可选的筛选器查询。查询结果被限制为仅搜索筛选器查询返回的结果。筛选过的查询由 Solr 进行缓存。它们对提高复杂查询的速度非常有用。 任何可以用 q 参数传递的有效查询,排序信息除外。

5. hl 当 hl=true 时,在查询响应中醒目显示片段。默认为 false。参看醒目显示参数上的 Solr Wiki 部分可以查看更多选项 hl=true

6. fl 作为逗号分隔的列表指定文档结果中应返回的 Field 集。默认为 “*”,指所有的字段。“score” 指还应返回记分。 *,score

二、对性能因素进行索引 1. useCompoundFile 通过将很多 Lucene 内部文件整合到单一一个文件来减少使用中的文件的数量。这可有助于减少 Solr 使用的文件句柄数目,代价是降低了性能。除非是应用程序用完了文件句柄,否则 false 的默认值应该就已经足够。

2. mergeFactor 决定低水平的 Lucene 段被合并的频率。较小的值(最小为 2)使用的内存较少但导致的索引时间也更慢。较大的值可使索引时间变快但会牺牲较多的内存。

3. maxBufferedDocs 在合并内存中文档和创建新段之前,定义所需索引的最小文档数。段 是用来存储索引信息的 Lucene 文件。较大的值可使索引时间变快但会牺牲较多的内存。

4.maxMergeDocs 控制可由 Solr 合并的 Document 的最大数。较小的值 (< 10,000) 最适合于具有大量更新的应用程序。

5. maxFieldLength 对于给定的 Document,控制可添加到 Field 的最大条目数,进而截断该文档。如果文档可能会很大,就需要增加这个数值。然而,若将这个值设置得过高会导致内存不足错误。

6. unlockOnStartup unlockOnStartup 告知 Solr 忽略在多线程环境中用来保护索引的锁定机制。在某些情况下,索引可能会由于不正确的关机或其他错误而一直处于锁定,这就妨碍了添加和更新。将其设置为 true 可以禁用启动锁定,进而允许进行添加和更新。

三、智能缓存

1. filterCache 通过存储一个匹配给定查询的文档 id 的无序集,过滤器让 Solr 能够有效提高查询的性能。缓存这些过滤器意味着对 Solr 的重复调用可以导致结果集的快速查找。更常见的场景是缓存一个过滤器,然后再发起后续的精炼查询,这种查询能使用过滤器来限制要搜索的文档数。 可以预热

2. queryResultCache 为查询、排序条件和所请求文档的数量缓存文档 id 的有序 集合。 可以 预热

3. documentCache 缓存 Lucene Document,使用内部 Lucene 文档 id(以便不与 Solr 惟一 id 相混淆)。由于 Lucene 的内部 Document id 可以因索引操作而更改,这种缓存不能自热。 不可以预热

Named caches 命名缓存是用户定义的缓存,可被 Solr 定制插件 所使用。 可以,如果实现了 org.apache.solr.search.CacheRegenerator 的话。

四、请求处理

若现有的功能不能满足业务需求,Solr 允许应用程序实现其自身的请求处理功能。比如,您可能想要支持您自己的查询语言或想要将 Solr 与您的用户配置文件相集成来提供个性化的效果。SolrRequestHandler 接口定义了实现定制请求处理所需的方法。实际上,除了所使用的那些默认的 “标准” 请求处理程序之外,Solr 还定义了其他几个请求处理程序:

1. 默认的 StandardRequestHandler 使用 Lucene Query Parser 语法处理查询,添加了排序和层面浏览。

2. DisMaxRequestHandler 被设计用来通过更为简单的语法来跨多个 Field 进行搜索。它也支持排序(使用与标准处理程序稍有不同的语法)和层面浏览。

3. IndexInfoRequestHandler 可以检索有关索引的信息,比如索引中的文档数或 Field 数。

4. 请求处理程序是由请求中的 qt 参数指定的。Solr servlet 使用参数值来查找给定的请求处理程序并将输入用于请求处理程序的处理。请求处理程序的声明和命名通过 solrconfig.xml 中的标记指定。要添加其他的内容,只需实现定制的 SolrRequestHandler 线程安全的实例即可,将其添加到 上述 定义好的 Solr,并将其包括到 如前所述 的类路径中,之后就可以通过 HTTP GET 或 POST 方法开始向其发送请求了。

五、响应处理

与请求处理类似,也可以定制响应输出。必须要支持老式的搜索输出或必须要使用二进制或加密输出格式的应用程序可以通过实现 QueryResponseWriter 来输出所需的格式。然而,在添加您自己的 QueryResponseWriter 之前,需要先深入研究一下 Solr 所自带的实现,如表 4 所示:
XMLResponseWriter 这个最为常用的响应格式以 XML 格式输出结果,如 第 1 部分 的博客应用程序所示。
XSLTResponseWriter XSLTResponseWriter 将 XMLResponseWriter 的输出转换成指定的 XSLT 格式。请求中的 tr 参数指定了要使用的 XSLT 转换的名称。指定的转换必须存在于 Solr Home 的 conf/xslt 目录。有关 XSLT Response Writer 的更多内容,请参见 参考资料。
JSONResponseWriter 用 JavaScript Object Notation (JSON) 格式输出结果。JSON 是一种简单、人类可读的数据转换格式,而且非常易于机器解析。
RubyResponseWriter RubyResponseWriter 是对 JSON 格式的扩展以便在 Ruby 中安全地使用结果。若有兴趣将 Ruby 和 Solr 结合使用,可以参考 参考资料 中给出的到 acts_as_solr 和 Flare 的链接。
PythonResponseWriter 对 JSON 输出格式的扩展以便在 Python eval 方法中安全地使用。

solr 1.3 更多扩展点

在 Solr 1.3 中,扩展 Solr 以及配置和重新整理扩展变得十分简单。以前,您需要编写一个 SolrRequestHandler 来实现新功能。这个方法的问题是其他 SolrRequestHandler 很难重用该功能。例如,您可能有更好的分类方法,但却想保留现有的查询与突出显示功能。为了解决这个问题,Solr 项目提出了将各种 SolrRequestHandler(比如 StandardRequestHandler 和 DismaxRequestHandler)重构为组件 — 称为 SearchComponent — 的想法,这些组件可以链接起来,形成一个新的 SolrRequestHandler。现在,您只要关注 SearchComponent 的新功能就可以了,不用再费神思考怎样才能最好地扩展、重用或复制其他功能。

不过请放心,现有的 SolrRequestHandler 仍然可以像以前一样无缝地工作,但它们现在仅仅是负责实际工作的围绕 SearchComponent 的包装器而已。表 1 介绍了一些新 SearchComponent 的详细信息。稍后,我还将在本文中提供有关表 1 中的两个组件的更多信息(MoreLikeThisComponent 和 SpellCheckComponent。参见 参考资料 中的 SearchComponent 链接)。

表 1. 常用的 SearchComponent
名称 说明和查询样例
QueryComponent 负责将查询提交到 Lucene 并返回 Document 的列表。

http://localhost:8983/solr/select?&q=iPod&start=0&rows=10
FacetComponent 决定结果集的分类。

http://localhost:8983/solr/select?&q=iPod&start=0&rows=10&facet=true&facet.field=inStock
MoreLikeThisComponent 为每个搜索结果查找与结果类似的文档,并返回这些结果。

http://localhost:8983/solr/select?&q=iPod&start=0&rows=10&mlt=true&mlt.fl=features&mlt.count=1
HighlightComponent 在搜索结果的正文中突出显示查询词语的位置。

http://localhost:8983/solr/select?&q=iPod&start=0&rows=10&hl=true&hl.fl=name
DebugComponent 返回有关查询的解析方式的信息,以及每个文档的记录方式的详细信息。

http://localhost:8983/solr/select?&q=iPod&start=0&rows=10&debugQuery=true
SpellCheckComponent 根据索引的内容对输入查询进行拼写检查,并提供其他备选方法。

http://localhost:8983/solr/spellCheckCompRH?&q=iPood&start=0&rows=10&spellcheck=true&spellcheck.build=true

查找相似页面

MoreLikeThisComponent 和 Solr 模式

MLT 要求字段被储存或使用检索词向量,检索词向量以一种以文档为中心的方式储存信息。MLT 通过文档的内容来计算文档中关键词语,然后使用原始查询词语和这些新词语创建一个新的查询。提交新查询就会返回其他查询结果。所有这些都可以用检索词向量来完成:只需将 termVectors="true" 添加到 schema.xml 中的声明。

在 Google 上尝试一个查询,您会注意到每一个结果都包含一个 “相似页面” 链接,单击该链接,就会发布另一个搜索请求,查找出与起初结果类似的文档。Solr 使用 MoreLikeThisComponent(MLT)和 MoreLikeThisHandler 实现了一样的功能。如上所述,MLT 是与标准 SolrRequestHandler 集成在一起的;MoreLikeThisHandler 与 MLT 结合在一起,并添加了一些其他选项,但它要求发布一个单一的请求。我将着重讲述 MLT,因为使用它的可能性更大一些。幸运的是,不需要任何设置就可以查询它,所以您现在就可以开始查询。

您可以向请求添加很多 HTTP 查询参数,并且大部分参数都有智能的默认值,因此我将着重讲述使用 MLT 必须了解的参数。(要了解更多的详细信息,请参见 参考资料 获得 Solr wiki 的 MLT 页面链接)。

表 2. MoreLikeThisComponent 参数
参数 说明 值域
mlt 在查询时,打开/关闭 MoreLikeThisComponent 的布尔值。 真|假
mlt.count 可选。每一个结果要检索的相似文档数。 > 0
mlt.fl 用于创建 MLT 查询的字段。 模式中任何被储存的或含有检索词向量的字段。
mlt.maxqt 可选。查询词语的最大数量。由于长文档可能会有很多关键词语,这样 MLT 查询可能会很大,从而导致反应缓慢或可怕的 TooManyClausesException,该参数只保留最关键的词语。 > 0
尝试下面的样例查询,然后检查返回结果中的 moreLikeThis 部分:

http://localhost:8983/solr/rss/select/?q=*%3A*&start=0&rows=10&mlt=true
&mlt.fl=description&mlt.count=3

[Solr的检索运算符]  “:” 指定字段查指定值,如返回所有值*:*
 “?” 表示单个任意字符的通配
 “*” 表示多个任意字符的通配(不能在检索的项开始使用*或者?符号)
 “~” 表示模糊检索,如检索拼写类似于”roam”的项这样写:roam~将找到形如foam和roams的单词;roam~0.8,检索返回相似度在0.8以上的记录。
 邻近检索,如检索相隔10个单词的”apache”和”jakarta”,”jakarta apache”~10
 “^” 控制相关度检索,如检索jakarta apache,同时希望去让”jakarta”的相关度更加好,那么在其后加上”^”符号和增量值,即jakarta^4 apache
 布尔操作符AND、||
 布尔操作符OR、&&
 布尔操作符NOT、!、- (排除操作符不能单独与项使用构成查询)
 “+” 存在操作符,要求符号”+”后的项必须在文档相应的域中存在
 ( ) 用于构成子查询
 [] 包含范围检索,如检索某时间段记录,包含头尾,date:[200707 TO 200710]
 {} 不包含范围检索,如检索某时间段记录,不包含头尾
date:{200707 TO 200710}
 / 转义操作符,特殊字符包括+ - && || ! ( ) { } [ ] ^ ” ~ * ? : /

LUCENE查询语法解析真正内幕

lucene的查询语法大解析
+ 和-表示对单个查询单元的修饰
and 和 or 和 not是对两个查询单元是否做交集或者做差集还是取反的操作的符号千万不要搞错了
如果你的检索式是:AB:china +AB:america
那么这个表示的是AB:china忽略不计可有可无必须满足第二个条件才是对的
而不是你所认为的必须满足这两个检索表达式
真正表示两个表达式必须满足的是通过AND来表示的
如果输入:AB:china AND AB:america这个时候lucene解析出来的
是:+AB:china +AB:america是这样的关系
要表达这样的关系你也可以用:
+AB:china AND +Ab:america来写或者+AB:china +AB:america
因为lucene的单元语法是: 修饰符 字段名:查询关键词 AND/OR/NOT 修饰符 字段名:查询关键词
这样的关系才是对的

===============================

Schema Design Considerations
indexed fields

indexed fields 的数量将会影响以下的一些性能:

索引时的时候的内存使用量
索引段的合并时间
优化时间
索引的大小

我们可以通过 将 omitNorms=“true” 来减少indexed fields数量增加所带来的影响。

stored fields

Retrieving the stored fields 确实是一种开销。这个开销,受每个文档所存储的字节影响很大。每个文档的所占用的空间越大,文档就显的更稀疏,这样从硬盘中读取数据,就需要更多的i/o操作(通常,我们在存储比较大的域的时候,就会考虑这样的事情,比如存储一篇文章的文档。)

可以考虑将比较大的域放到solr外面来存储。如果你觉得这样做会有些别扭的话,可以考虑使用压缩的域,但是这样会加重cpu在存储和读取域的时候的负担。不过这样却是可以较少i/0的负担。

如果,你并不是总是使用 stored fields 的话,可以使用stored field的延迟加载,这样可以节省很多的性能,尤其是使用compressed field 的时候。

Configuration Considerations
mergeFactor

这个是合并因子,这个参数大概决定了segment(索引段)的数量。

合并因子这个值告诉lucene,在什么时候,要将几个segment合并成为一个segment, 合并因子就像是一个数字系统的基数一样。

比如说,如果你将合并因子设成10,那么每往索引中添加1000个文档的时候,就会创建一个新的索引段。当第10个大小为1000的索引段添加进来的时 候,这十个索引段就会被合并成一个大小为10,000的索引段。当十个大小为10,000的索引段生成的时候,它们就会被合并成一个大小为100,000 的索引段。如此类推下去。

这个值可以在 solrconfig.xml 中的 *mainIndex*中设置。(不用管indexDefaults中设置)
mergeFactor Tradeoffs

较高的合并因子

会提高索引速度
较低频率的合并,会导致 更多的索引文件,这会降低索引的搜索效率

较低的合并因子

较少数量的索引文件,能加快索引的搜索速度。
较高频率的合并,会降低索引的速度。

Cache autoWarm Count Considerations

当一个新的 searcher 打开的时候,它缓存可以被预热,或者说使用从旧的searcher的缓存的数据来“自动加热”。autowarmCount是这样的一个参数,它表示从旧 缓存中拷贝到新缓存中的对象数量。autowarmCount这个参数将会影响“自动预热”的时间。有些时候,我们需要一些折中的考虑,seacher启 动的时间和缓存加热的程度。当然啦,缓存加热的程度越好,使用的时间就会越长,但往往,我们并不希望过长的seacher启动时间。这个autowarm 参数可以在solrconfig.xml文件中被设置。

详细的配置可以参考solr的wiki。
Cache hit rate(缓存命中率)

我们可以通过solr的admin界面来查看缓存的状态信息。提高solr缓存的大小往往是提高性能的捷径。当你使用面搜索的时候,你或许可以注意一下filterCache,这个是由solr实现的缓存。

详细的内容可以参考 solrCaching这篇wiki。
Explicit Warming of Sort Fields

如果你有许多域是基于排序的,那么你可以在"newSearcher"和"firstSearcher"event listeners中添加一些明显需要预热的查询,这样FieldCache 就会缓存这部分内容。
Optimization Considerations

优化索引,是我们经常会做的事情,比如,当我们建立好索引,然后这个索引不会再变更的情况,我们就会做一次优化了。

但,如果你的索引经常会改变,那么你就需要好好的考虑下面的因素的。

当越来越多的索引段被加进索引,查询的性能就会降低, lucene对索引段的数量有一个上限的限制,当超过这个限制的时候,索引段可以自动合并成为一个。
在同样没有缓存的情况下,一个没有经过优化的索引的性能会比经过优化的索引的性能少10%……
自动加热的时间将会变长,因为它依赖于搜索。
优化将会对索引的分发产生影响。
在优化期间,文件的大小将会是索引的两倍,不过最终将会回到它原来的大小,或者会更小一点。

优化,会将所有的索引段合并成为一个索引段,所以,优化这个操作其实可以帮助避免“too many files”这个问题,这个错误是由文件系统抛出的。
Updates and Commit Frequency Tradeoffs

如果从机太经常从主机更新的话,从机的性能是会受到影响的。为了避免,由于这个问题而引起的性能下降,我们还必须了解从机是怎样执行更新的,这样我们才能 更准确去调节一些相关的参数(commit的频率,spappullers,autowarming/autocount),这样,从机的更新才不会太频 繁。

执行commit操作会让solr新生成一个snapshot。如果将postCommit参数设成true的话,optimization也会执行snapShot.
slave上的Snappuller程序一般是在crontab上面执行的,它会去master询问,有没有新版的snapshot。一旦发现新的版本,slave就会把它下载下来,然后snapinstall.
每次当一个新的searcher被open的时候,会有一个缓存预热的过程,预热之后,新的索引才会交付使用。

这里讨论三个有关的参数:

number/frequency of snapshots ----snapshot的频率。
snappullers 是 在crontab中的,它当然可以每秒一次、每天一次、或者其他的时间间隔一次运行。它运行的时候,只会下载slave上没有的,并且最新的版本。
Cache autowarming 可以在solrconfig.xml文件中配置。

如果,你想要 的效果是频繁的更新slave上的索引,以便这样看起来比较像“实时索引”。那么,你就需要让snapshot尽可能频繁的运行,然后也让 snappuller频繁的运行。这样,我们或许可以每5分钟更新一次,并且还能取得不错的性能,当然啦,cach的命中率是很重要的,恩,缓存的加热时 间也将会影响到更新的频繁度。

cache对性能是很重要的。一方面,新的缓存必须拥有足够的缓存量,这样接下来的的查询才能够从缓存中受益。另一方面,缓存的预热将可能占用很长一段时间,尤其是,它其实是只使用一个线程,和一个cpu在工作。snapinstaller太频繁的话,solr slave将会处于一个不太理想的状态,可能它还在预热一个新的缓存,然而一个更新的searcher被opern了。

怎么解决这样的一个问题呢,我们可能会取消第一个seacher,然后去处理一个更新seacher,也即是第二个。然而有可能第二个seacher 还没有被使用上的时候,第三个又过来了。看吧,一个恶性的循环,不是。当然也有可能,我们刚刚预热好的时候就开始新一轮的缓存预热,其实,这样缓存的作用压根就没有能体现出来。出现这种情况的时候,降低snapshot的频率才是硬道理。
Query Response Compression

在有些情况下,我们可以考虑将solr xml response 压缩后才输出。如果response非常大,就会触及NIc i/o限制。

当然压缩这个操作将会增加cpu的负担,其实,solr一个典型的依赖于cpu处理速度的服务,增加这个压缩的操作,将无疑会降低查询性能。但是,压缩后的数据将会是压缩前的数据的6分之一 的大小。然而solr的查询性能也会有15%左右的消耗。

至于怎样配置这个功能,要看你使用的什么服务器而定,可以查阅相关的文档。
Embedded vs HTTP Post

使用embeded 来建立索引,将会比使用xml格式来建立索引快50%。

RAM Usage Considerations(内存方面的考虑)
OutOfMemoryErrors

如果你的solr实例没有被指定足够多的内存的话,java virtual machine也许会抛outof memoryError,这个并不对索引数据产生影响。但是这个时候,任何的 adds/deletes/commits操作都是不能够成功的。
Memory allocated to the Java VM

最简单的解决这个方法就是,当然前提是java virtual machine 还没有使用掉你全部的内存,增加运行solr的java虚拟机的内存。

Factors affecting memory usage(影响内存使用量的因素)

我想,你或许也会考虑怎样去减少solr的内存使用量。

其中的一个因素就是input document的大小。

当我们使用xml执行add操作的时候,就会有两个限制。

document中的field都是会被存进内存的,field有个属性叫maxFieldLength,它或许能帮上忙。
每增加一个域,也是会增加内存的使用的。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值