1.什么是Solr
Solr它是一种开放源码的、基于 Lucene Java 的搜索服务器,易于加入到 Web 应用程序中。Solr提供了层面搜索(就是统计)、命中醒目显示并且支持多种输出格式(包括XML/XSLT 和JSON等格式)。它易于安装和配置,而且附带了一个基于HTTP 的管理界面。可以使用 Solr 的表现优异的基本搜索功能,也可以对它进行扩展从而满足企业的需要。
- 高级的全文搜索功能
- 专为高通量的网络流量进行的优化
- 基于开放接口(XML和HTTP)的标准
- 综合的HTML管理界面
- 可伸缩性-能够有效地复制到另外一个Solr搜索服务器
- 使用XML配置达到灵活性和适配性
- 可扩展的插件体系
2.定义Scheme
2.1常用类型
- name,这里定的的name将在field字段中用于type参数
- sortMissingLast,若为true则当document不包含该字段是排序靠后
- onitNorms,若为true则意味着索引阶段禁用了文档boost和域的boost及长度标准化。(即域没有特殊打分区别。)
- precisionStep,精度值
- solr.TextField,该类型的域将使用QueryParser搜索,支持分词,可自定义分词器
2.2 定义Field
<fields>
<field name="id" type="string" indexed="true" stored="true" required="true" multiValued="false"/>
<field name="path" type="text_smartcn" indexed="false" stored="true" multiValued="false" termVector="true" />
<dynamicField name="public_rand*" type="random" indexed="true" stored="false"/>
</fields>
<uniqueKey>id</uniqueKey>
<copyField source="content" dest="pinyin"/>
- field: 固定的字段设置
- dynamicField: 动态的字段设置,用于后期自定义字段,*号通配符.
- copyField ,一般用于检索时用的字段这样就只对这一个字段进行索引
- uniqueKey,主键
- indexed,缺省true。 说明这个数据应被搜索和排序
- stored,缺省true。说明这个字段将被包含在搜索结果中。
- multiValued,字段多于一个值的时候,可设置为true。
3.查询语句
3.1 最通用的查询
案例:q=60eb1384-038e-42f6-8350-0b77c2025837&fq=customerId:95955047-a739-4d4a-9ca0-af8e5d75bcbc&start=0&rows=1&fl=id,customerId,score&df=id
- q:查询参数字段,必填。多个q&时,仅第一个有效。支持AND/OR/-(NOT)布尔关系运算。
- field和value用”:”分割。
- 范围查询:[* TO *] ,时间和字符串亦可使用
- 时间:NOW 现在,NOW-1DAY 昨天这个时间点。NOW/DAY四舍五入到天 (YEAR, MONTH, DAY, HOUR, MINUTE, SECOND, MILLISECOND)
- fq:过滤结果集参数,可结合filterCache使用,语法与q一致。多个fq&是AND关系。
- start,rows:起始及页容量,分页相关
- fl:定义返回field,*其中定义score,可返回文档索引得分;*亦可以返回函数结果值
- df,q中默认查询字段,如果不设置,需显式标注field。
3.2 高亮查询
案例:&hl=true&hl.fl=id,customerId&hl.simple.pre=<em>&hl.simple.post=</em>
- hl:true,设置使用高亮
- hl.fl:定义高亮的字段,字段若不出现在q中,则返回不会加高亮处理
- hl.simple.pre/post:高亮处理
3.3 group查询
案例:&fl=id,customerId&group=true&group.field=id
- group:true,设置使用分组
- group.field:设置分组字段,必填,多个字段用&分割,会返回多个结果集
- group.limit:分页容量
- group.offset:分页起始
- group.query:将单独返回经过query筛选的结果集
- group.ngourps:返回结果数
3.4 facet查询
案例:&facet=true&facet.query=60eb1384-038e-42f6-8350-0b77c2025837&facet.field=id&facet.field=customerId&facet.prefix=0
- facet:true,设置facet查询
- facet.query:facet查询数据结果集,不设置则facet.querys为空。设置了df则不用显式field
- facet.field:返回按字段分别的结果集,多个用&分割,如果不设置则facet.fields返回空。
- facet.prefix:查询前缀,限制返回“0”开头的结果
- facet.offset=0 : 表示在当前排序情况下的偏移,可以做分页
- facet.limit=100 : 返回的数目
- facet.missing=false : 是否返回没有值的field
4 排序语句
案例:
sum(
recip(if(exists(callCount),callCount,0),1,1,1), //未拨号的优先,优于时间一个数量级
product(map(if(exists(failCallCount),failCallCount,0),0,3,0),-1000), //存在无效用户
div(ms(NOW,lastCallDateTime),3.16e12),
div(ms(NOW,createTime),3.16e12)
)
简单排序可以使用sort,但涉及到复杂业务排序的,建议使用bf函数计算得分排序。
*排序是通过查询筛选后,对结果进行的展示序列调整,所以用于排序的字段显然是可进行计算和比较的。
*排序是通过查询筛选后,对结果进行的展示序列调整,所以用于排序的字段显然是可进行计算和比较的。
- sum(x,y,...):累加/sub(x,y):x-y/
- product(x,y,...):累乘/div(x,y):x除以y,”x/y”/mod(x,y)取模,“x%y”
- pow(x,y):次方/sqrt(x),开方
- map(x,min,max,target):如果min<=x<=max,则输出target,否则输出x
- scale(x,minTarget,maxTarget):将x压缩到值域之内。
- max(x,y):取两数之大/min(x,y):取两数之小
- linear(x,m,c):线性函数,m*x+c
- recip(x,m,a,b):压缩函数,a/(m*x+b),若x>0,将x压缩在(0,a/b]之间。m为压缩比例。一般a和b设置成一样。这样x就在(0,1]之间
- ms(x,y) 计算x时间点-y时间点的long值
5 缓存设置
5.1 缓存类型
- documentCache 文档缓存
- filterCache fq查询缓存
- queryResultCache 相同查询条件结果缓存
- fieldValueCache
5.2 documentCache
如果ducoment曾经被查询过,则会缓存,查该document上任意field都会优先击中缓存。
5.3 filterCache
相同的fq语句结果将会被缓存,并与q查询返回的结果做结果交集返回。注意:只要fq的语句是一样的,则使用同一份缓存。
5.4 queryResultCache
相同的查询语句结果将会被缓存,以后相同的语句再次使用将使用缓存数据。
5.5 fieldValueCache
f
acet.field是multivalue时,将进行缓存。
5.6 缓存失效
solr的缓存生命周期是由org.apache.solr.search.SolrIndexSearcher管理的,索引产生任何变更,solr默认将new出新的solrIndexSearcher对象,也即所有缓存会直接失效。
因此在设计solr core中的缓存时,要将经常变更的字段或数据单独剥离成core或者不要在经常变动的数据上设置缓存,否则反倒会增加性能消耗。
因此在设计solr core中的缓存时,要将经常变更的字段或数据单独剥离成core或者不要在经常变动的数据上设置缓存,否则反倒会增加性能消耗。