solr查询语法

solr查询语法solr的基本查询语法,总结自维基百科solr基于搜索解析插件和解析器(https://wiki.apache.org/solr/QueryParser),solr支持多种查询语法

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

参考文章

  1. http://lucene.apache.org/solr/guide/6_6/the-dismax-query-parser.html
  2. https://mxsfengg.iteye.com/blog/352191
  3. https://wiki.apache.org/solr/FunctionQuery#top

今天的文章solr查询语法分享到此就结束了,感谢您的阅读。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/64984.html

(0)
编程小号编程小号

相关推荐

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注