使用Solr实现MySQL基础查询

随着业务的数据量的不断增大,MySQL数据库的查询统计压力不断增加,不得不将数据的查询和统计功能转移到类似搜索引擎的应用服务器中。
将数据转存到SolrCloud中,以前将介绍怎么使用Solr实现类似MySQL的基础查询功能。

设计如下数据结构

1
2
3
4
5
6
7
8
9
10
11
12
13
mysql> desc call_record;
+-------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| fm | varchar(64) | YES | | NULL | |
| vm | varchar(11) | YES | MUL | NULL | |
| tm | varchar(64) | YES | | NULL | |
| status | int(11) | YES | | NULL | |
| startTime | datetime | YES | | NULL | |
| endTime | datetime | YES | | NULL | |
| callMinutes | int(11) | YES | | 0 | |
+-------------+-------------+------+-----+---------+----------------+

下面通过给出相关SQL查询统计语句,然后对方翻译成Solr查询语句。

普通查询

SQL查询语句:

1
2
select id,fm,vm,tm,callMinutes from call_record where 
status=0 and startTime>='2017-03-31' order by id desc limit 0,10;

Solr查询URL:

1
2
3
http://SolrCloud01:9002/solr/call_record_shard1_replica1/select?
q=status:0&fq=startTime[2017-03-31T00:00:00 TO *]&fl=id,fm,vm,tm,callMinutes
&sort=id desc&start=0&rows=10&wt=xml&indent=true

统计

SQL查询语句:

1
2
select sum(callMinutes),avg(callMinutes),max(callMinutes),min(callMinutes) 
from call_record where status=0

Solr查询URL:

1
2
http://SolrCloud01:9002/solr/call_record_shard1_replica1/select?
q=status:0&rows=0&wt=xml&indent=true&stats=on&stats.field=callMinutes

Solr查询的结果包括以下统计数据:

1
2
3
4
5
6
7
8
min             最小值
max 最大值
sum 总和
count 记录数,也就是多少行记录
missing 结果集中,有多少条记录是空值
sumOfSquares 平方和(x1^2 + x2^2+xn^2)
mean 平均数(x1+x2+xn)/n
stddev 标准差

IN查询

SQL查询语句:

1
select * from call_record where status in (0,1) order by id desc limit 0,10;

Solr查询URL:

1
2
3
http://SolrCloud01:9002/solr/call_record_shard1_replica1/select?
q=(status:0 OR status:1)&fl=id,fm,vm,tm,callMinutes
&sort=id desc&start=0&rows=10&wt=xml&indent=true

字段分组统计次数

SQL查询语句:

1
select fm,count(callMinutes) from call_record where status=0 group by fm

Solr查询URL-01:

1
2
3
4
5
6
7
8
9
http://SolrCloud01:9002/solr/call_record_shard1_replica1/select?
q=status:0&rows=0&wt=json&indent=true&facet=on&facet.field=fm&facet.limit=-1

注:
facet.limit=-1表示查询出所有的记录
这个查询查询比较耗费资源不建议键facet.limit设置为-1
这里的结果集默认按照count降序排列,还可设置facet.solr=index表示按照fm进行自然排序
当然Solr还支持只查询出次数大于10次的记录facet.mincount=10
需要查询fm的数量时会相对比较麻烦,只能将所有的结果查询出来;

Solr查询URL-02

1
2
3
4
5
6
7
8
9
http://SolrCloud01:9002/solr/call_record_shard1_replica1/select?
q=status:0&rows=10&wt=json&indent=true&group=true&group.field=fm&group.limit=1

注:
如果对于集群应用时,不能使用group进行查询,结果集会不准确
如果自行控制,将需要group的数据存放在同一个分片中时才能使用;
不支持结果集排序
不支持查询出次数大于10次的记录
需要查询fm的数量时比较方便,增加group.ngrouops=true

字段分组统计

SQL查询语句:

1
2
select fm,count(callMinutes),sum(callMinutes),avg(callMinutes),
max(callMinutes),min(callMinutes) from call_record where status=0 group by fm

Solr查询URL:

1
2
3
4
5
6
7
8
http://SolrCloud01:9002/solr/call_record_shard1_replica1/select?
q=status:0&rows=0&wt=json&indent=true&stats=on
&stats.field={!tag=piv1}callMinutes
&facet=on&facet.pivot={!stats=piv1}fm&facet.mincount=1&facet.limit=10

注:
不支持排序
需要查询出fm的数量只能查询出全量数据