源码网,源码论坛,源码之家,商业源码,游戏源码下载,discuz插件,棋牌源码下载,精品源码论坛

 找回密码
 立即注册
查看: 677|回复: 24

[相关技巧] 漂流瓶推送需求的逻辑实现代码

[复制链接]

7万

主题

861

回帖

32万

积分

论坛元老

Rank: 8Rank: 8

积分
329525
发表于 2010-12-17 11:09:28 | 显示全部楼层 |阅读模式
假想有一个瓶子池,当点击附近标签的时候要从池里面推送一个瓶子给用户.推送按照一定的逻辑对池里的瓶子排序,排序规则主要由两个数据决定:瓶子上次推送时间和与用户之间的距离. 本身这两个数据之间没有关联,并且sql语句里面的排序规则不能满足要求:sql里只有数据中前一个排序条件出现相同的情况时才考虑后面的排序条件.实际情况是如果按先推送时间后距离排序的话,距离就起不了作用,反之亦然.

要让两个数据产生关联,有一种做法是将这两个数据做加法或减法后排序,但是这必须要考虑以下情况

两个数据的数据类型不一致,一个是日期类型另一个是双精度类型
必须统一两个数据的排序方向,不能推送时间取正序而距离取反序,视实际需求而定
将这两个数据都转换成一种类型,需要一个系数来平衡它们.如果一个数据数量级极大,另一个数据数量极小,那么极小的数据再怎么变化对极大的数据产生的影响也可以忽略
下面来具体实现,首先将日期类型转换为双精度类型,操作两个数值类型的数据相对来说比较容易.mysql里面正好有这样的函数:unix_timestamp(date) -- 直接返回内部时戳值
复制代码 代码如下:
-- 相差一天的时戳值
select unix_timestamp('2010-12-13') - unix_timestamp('2010-12-12')
-- 计算结果:86400

关于已知两地经纬度计算距离的公式,在网上搜索了一个,计算结果还算满意
复制代码 代码如下:
ROUND((2 * ASIN(SQRT(POWER(SIN(((LAT*PI()/180.0)-(plat*PI()/180.0)) / 2), 2) + COS(LAT*PI()/180.0) * COS(plat*PI()/180.0) * POWER(SIN((LNG*PI()/180.0-plng*PI()/180.0) / 2), 2))))*6378.137*10000,3)/10000)

接下来考虑两个数据的排序方向,我们希望的是:距离上次推送时间越久越好,与用户之间的距离越近越好.时间越久那么计算得出的差值就越大,两个数据直接相加明显不行.这里只好将时间取负值来满足与用户之间的距离越近越好的要求,然后再按正序排列.

再来让这两个数在同一数量级,根据数据测试,时间取的是秒,距离算出来是公里,直接把距离乘上一个系数(1000)换算成米来平衡二者.

最终的推送语句如下:
复制代码 代码如下:
select BottleID,(ROUND((2 * ASIN(SQRT(POWER(SIN(((LAT*PI()/180.0)-(plat*PI()/180.0)) / 2), 2) + COS(LAT*PI()/180.0) * COS(plat*PI()/180.0) * POWER(SIN((LNG*PI()/180.0-plng*PI()/180.0) / 2), 2))))*6378.137*10000,3)/10000)as Distance from Bottle
inner join Venue_Mapabc
on Bottle.VenueID = Venue_Mapabc.VenueID
where Bottle.IsDrift =1 and Bottle.IsEmpty =1 and IsFinished=0 and Venue_Mapabc.City = pCity
-- and (ROUND((2 * ASIN(SQRT(POWER(SIN(((LAT*PI()/180.0)-(plat*PI()/180.0)) / 2), 2) + COS(LAT*PI()/180.0) * COS(plat*PI()/180.0) * POWER(SIN((LNG*PI()/180.0-plng*PI()/180.0) / 2), 2))))*6378.137*10000,3)/10000)>1.5
order by

(-(unix_timestamp(now())-unix_timestamp(Bottle.PlaceTime))*0.5 +
(ROUND((2 * ASIN(SQRT(POWER(SIN(((LAT*PI()/180.0)-(plat*PI()/180.0)) / 2), 2) + COS(LAT*PI()/180.0) * COS(plat*PI()/180.0) * POWER(SIN((LNG*PI()/180.0-plng*PI()/180.0) / 2), 2))))*6378.137*10000,3)/10000)*0.5*1000)


limit 1;

前端截图:

回复

使用道具 举报

6

主题

2万

回帖

425

积分

中级会员

Rank: 3Rank: 3

积分
425
发表于 2022-8-9 09:26:56 | 显示全部楼层
看看看看看看看看看看看看看看看看看看看看看看看看看看看
回复 支持 反对

使用道具 举报

4

主题

1万

回帖

60

积分

注册会员

Rank: 2

积分
60
发表于 2022-8-15 17:29:46 | 显示全部楼层
很好,谢谢分享
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

115

积分

注册会员

Rank: 2

积分
115
发表于 2022-11-20 04:50:21 | 显示全部楼层
很不错的源码论坛
回复 支持 反对

使用道具 举报

2

主题

2万

回帖

380

积分

中级会员

Rank: 3Rank: 3

积分
380
发表于 2022-12-14 05:22:23 | 显示全部楼层
呵呵呵呵呵呵
回复 支持 反对

使用道具 举报

1

主题

2万

回帖

182

积分

注册会员

Rank: 2

积分
182
发表于 2023-4-9 22:21:12 | 显示全部楼层
而快乐你们快乐马年快乐
回复 支持 反对

使用道具 举报

2

主题

2万

回帖

69

积分

注册会员

Rank: 2

积分
69
发表于 2023-5-7 23:41:27 | 显示全部楼层
看到这帖子真是高兴!
回复 支持 反对

使用道具 举报

0

主题

2万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2023-8-30 04:49:35 | 显示全部楼层
源码源码源码源码源码源码源码源码源码源码源码源码源码
回复 支持 反对

使用道具 举报

3

主题

2万

回帖

156

积分

注册会员

Rank: 2

积分
156
发表于 2023-9-3 02:28:19 | 显示全部楼层
谢谢您的分享!
回复 支持 反对

使用道具 举报

0

主题

1万

回帖

0

积分

中级会员

Rank: 3Rank: 3

积分
0
发表于 2023-11-29 14:32:55 | 显示全部楼层
8888888888888888
回复 支持 反对

使用道具 举报

高级模式
B Color Image Link Quote Code Smilies

本版积分规则

手机版|小黑屋|网站地图|源码论坛 ( 海外版 )

GMT+8, 2024-11-23 13:09 , Processed in 0.074339 second(s), 26 queries .

Powered by Discuz! X3.4

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表