solr的基本查询语法,总结自维基百科solr
基于搜索解析插件和解析器, solr支持多种查询语法。
查询语法
介绍默认解析器的查询语法,以及如何指定特定的解析器。
Local Params
LocalParams的语法格式是{! k1=va k2=v2 ...}
,可以认为是对普通查询的一个补充限制。
solr默认的解析时lucene解析器,solr支持搜索时使用LocalParams语法。举个例子,
q={!lucene q.op=AND df=text}myfield:foo +bar -baz
上面这个例子表示,搜索时使用的是lucene解析器
, q.op=AND
,默认查询字段是text
,剩下的myfield:foo +bar -baz
才是普通常见的搜索语法。
在standard Solr search handler中,q={!func}popularity
等价于 defType=func&q=popularity
。
时间查询
如果字段类型是solr的DateField
类型,注意时间是格林威治时间,另外solr中的部分跟时间相关的函数也可以用的上。
- timestamp:[* TO NOW]
截止时间是当前 - pubdate:[NOW-1YEAR/DAY TO NOW/DAY+1DAY]
起始时间是一年前的日期,结束时间是明天日期 - createdate:[1976-03-06T23:59:59.999Z TO 1976-03-06T23:59:59.999Z+1YEAR]
结束时间是开始时间的一年后 - createdate:[1976-03-06T23:59:59.999Z/YEAR TO 1976-03-06T23:59:59.999Z]
开始时间是1976年
函数查询
将solr字段的值作用到函数
中,影响打分排序。典型的一个例子
**q={!func}log(foo)等价于defType=func&q=log(foo)**这就是最普通的函数查询。
_val_常量函数
q=boxname:findbox+_val_:"product(product(x,y),z)"
可以认为x,y,z三个字段是箱子的长宽高,boxname是箱子的名称字段,这里就是查询名称为findbox的箱子,得分score=名字的匹配度 + 箱子的体积(xyz),搜索结果自然很大程度是依靠箱子的体积进行排序的。
score中有很大一部分是箱子的体积。
如果想用箱子的密度进行排序呢?如下:
http://localhost:8983/solr/select/?q=boxname:findbox+
_val_:"div(weight,product(product(x,y),z))"&fl=boxname,x,y,z,weight,score
你可能已经看出来了,在用q主查询的时候,_val_后可以跟一个函数(需要用双引号包裹),也可以跟一个业务字段(不强制用双引号包裹),匹配得分很大程度上就是这个函数或字段的值
map函数
map函数有两种个数,如下:
map(x,min,max,target)
map(x,min,max,target,value)
第一种格式: 业务字段x的值如果在数字区间[min,max]中,则返回target,否则返回x的值。
第一种格式: 业务字段x的值如果在数字区间[min,max]中,则返回target,否则返回value的值。
需要注意的是,x必须是业务字段,min,max必须是数字,而target和value既可以是业务字段,又可以是数字。可结合函数_val_
进行测试。 如:
q=_val_:"map(x,0,2,y,z)"&wt=json&fl=*,score&q.op=AND
x在[0,2]区间范围内时,返回业务字段y的值,否则返回业务字段z的值。
特别需要说明的是,当x == NULL时,会被当做最小值0来处理
scale比例函数
scale(x,minTarget,maxTarget),该函数将字段x的值归一到区间[minTarget,maxTarget]中,而且是线性归一。
举例来说,如果现在有10000个文档,业务字段x的值分散不一,最小的有0,最大的有150,那么就认为 0对位到minTarget,150对位到maxTarget,其他的值线性地落在这条线段上
你可能已经猜测到了,这其实是有风险的,假如所有文档的x值是一样的,那么该函数的返回值永远是minTarget。当然,在某些场合下,这也没什么大不了的,仅仅是这些文档的打分都一样而已。
query函数
下面几个例子是假设&defType=func
的基础上的,我们看看是什么意思
1: q=product(popularity, query({!dismax qf=text v='solr rocks'}))
2: q=product(popularity, query($qq))&qq={!dismax qf=text}solr rocks
3: q=product(popularity, query($qq,0.1))&qq={!dismax qf=text}solr rocks
1与2是等价的,1中的v参数使用了local params语法;2则是使用了变量引用语法。
3是对2的一个补充,对不满足{!dismax qf=text}solr rocks
条件的文档,设置其分数为0.1。
linear线性函数
sum(product(m,x),c)等价于linear(x,m,c)
recip倒数函数
recip(x,m,a,b) 等价于 a/(m*x+b)
看一个例子
recip(rord(creationDate),1,1000,1000)
等价于1000/rord(creationDate)+1000
,
可以知道,creationDate越接近现在,分母越小,表达式值越大,打分越高。
但是在solr1.4之后,最佳实战是避免使用ord
函数和rord
函数,直接从时间类型字段date
中获取加权提升值,如利用ms()
函数。
ms毫秒函数
- ms()
等价于ms(NOW),值为epoch纪元到现在的毫秒数 - ms(a)
如ms(NOW/DAY)
,ms(2000-01-01T00:00:00Z)
,ms(mydatefield)
,
值为epoch纪元到函数参数时间之间的毫秒数 - ms(a,b)
如ms(NOW,mydatefield)
,
ms(mydatefield,2000-01-01T00:00:00Z)
,
ms(datefield1,datefield2)
表示时间a-时间b的毫秒数
如何给最新的文档打适当更高的分数呢?可以参考http://wiki.apache.org/solr/SolrRelevancyFAQ#How_can_I_boost_the_score_of_newer_documents
查询示例
1.文档结构定义中,存在item_title,和shop_name两个字段,都是text_ik类型。如果item_title能够ik分词匹配到,分数设置为1。 再加上shop_name的匹配分数,可以使用下面的查询q:
q=(item_title:毛衣)^=1 shop_name:毛衣
2.查询所有字段中含有xiao
的文档,如果名字字段中还含有ming
,则提升分数。
q=xiao&bq=name:ming&defType=dismax
主查询是q=xiao,必须满足条件的文档才被匹配到。另外,在这个基础上,bq=name:ming
的文档得到分数提升。
3.满足name=xiao的文档,打分时再加上字段x+字段y的值。
q=name:xiao&bf=sum(x,y)&defType=edismax
等价于
q=name:xiao&bq={!func}sum(x,y)&defType=edismax
参考文章
- http://lucene.apache.org/solr/guide/6_6/the-dismax-query-parser.html
- https://mxsfengg.iteye.com/blog/352191
- https://wiki.apache.org/solr/FunctionQuery#top
今天的文章solr查询语法分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/64984.html