mongodb随机查询一条记录的正确方法!
关于从mongodb库中随机取出一条记录的方法的博文很多,其中都提到了下面三种方法:
1、skip过随机数量的记录。
DBCursor cursor = coll.find(query);
int rint = random.nextInt(cursor.count());
cursor.skip(rint);
DBObject word = null;
if(cursor.hasNext()){
word = cursor.next();
cursor.close();
}
很多人说不推荐这种做法,如果数据量不是那么巨大,10万个记录以内完全可以使用这种方法。
其实让我写存储引擎的话,我肯定把这个方法搞成最快的。只查询,又不排序。用作查询的条件建好索引后,至少和方法2一样快。通过索引进行物理skip很容易直接就定位到要找的数据了。
2、增加一个random数值字段。
var random=Math.random();
var result=db.user.findOne({"random":{"$lt":random}});
if(result==null){
result=db.user.findOne({"random":{"$gte":random}});
}
很多人说这是效率较高的一种可行方法,但是如果你信了,又不加验证,那真叫坑了爹了!下面我们就分析一下。
findOne的机制是取出查询结果的第一条。这有什么问题看出来了吗?
内部的查询结果是按random字段排序的吗?问题显然不是那么好回答吧!通过试验发现:如果不建立索引,查询的结果是按照存储顺序排的。也就是说不管查询条件是小于,还是大于等于,都会取到符合条件的最早入库的记录。这大大降低了随机性,有没有啊。如果建立索引,查询的结果是按照random由小到大排序的,此时如果用小于等于条件,始终取回来的是random值最小的值。这就没有随机性了,是不是呢。也就是说,如果random升序需要使用大于条件,如果降序需要使用小于条件。但是没有指定排序的时候内部怎么给排序,你敢肯定吗?如果不敢肯定,是不是就得指定排序方式。从底层来说,你指定的排序方式跟索引的物理存放顺序一致才能达到最高的效率。
3、增加一个random空间位置字段。
db.coll.ensureIndex({ random: '2d' }) result = db.coll.findOne({ random: { $near: [Math.random(), 0] } })
将random建立为多值字段,两值得就可以,建立索引的时候当地理位置使用。取值的时候随机生成一个坐标,然后取离这个点最近一个值。
很多人把这个方法也列在推荐方法中,但是真的是高效率的方法吗?这个方法比较麻烦,很多人应该都没验证,直接抄写到自己博客了。其实用脑袋想想,这个方法比第二个方法更不靠谱呢。可以自己思考一种算法——在一群坐标中找出离某个坐标最近的一个坐标。好难哦,坐标点哎,他们本身并没有一个大小关系,也就是说没有天然的顺序。那些牛逼的查找算法都是基于排序的(基于哈希的本质也是基于排序的)。
那么怎么办?方法一:对两个分量建立两个索引。然后以查询点为中心点构建一个较小的矩形区域,查询的时候就是两个分量的范围的与关系。如果没查到结果扩大矩形区域,如果查询的结果过多,缩小矩形区域,这里就可以用二分法了。然后在矩形区域内精确计算距离。方法二:空间点按照相互距离聚类,然后将类别中心存储起来,然后采用方法一找到一个最近的类别中心,然后再在这个内别中使用方法一。方法三:求出所有点的外接矩形,然后把区域等分成4块的方法构建4叉树索引。构建过程就是把某个区域分成四等分,再把其中一份分成4等分,直到每个区域的点数少于给定值。这样查询的时候每层确定一次范围。最后一层暴力计算距离。我是想不出来更牛B的方法了!
可见最近空间距离的计算不轻松啊!
mongodb随机查询一条记录的正确方法!的更多相关文章
- 【面经】面试官:如何以最高的效率从MySQL中随机查询一条记录?
写在前面 MySQL数据库在互联网行业使用的比较多,有些小伙伴可能会认为MySQL数据库比较小,存储不了很多的数据.其实,这些小伙伴是真的不了解MySQL.MySQL的小不是说使用MySQL存储的数据 ...
- mysql_oracle_随机查询几条记录
数据库的随机查询SQL 1. Oracle,随机查询20条 select * from ( select * from 表名 order by dbms_random.value ) where ...
- 随机提取N条记录[多种数据库方法]
随机提取10条记录的例子: Sql server: select top 10 * from 表 order by newid() Access: SELECT top 10 * FROM 表 ORD ...
- mongodb索引--1亿条记录的查询从55.7秒到毫秒级别<补充版>
从头开始,验证mongodb的索引的好处.(window7环境下) 下载mongodb服务器,并解压到d盘,并使用以下命令启动 mongod --dbpath D:\mongodb\data mong ...
- TODO:从数据库中随机抽取一条记录
TODO:从数据库中随机抽取一条记录 1.最直接,最粗暴的方法先计算记录的总数,然后选择一个从0到记录总数之间的随机数n,利用skip跳过n条记录,这是效率低下的的方法,首先的记录总数,在用skip会 ...
- mysql 随机选取一条记录
要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RAND() LIMIT 1. 1 2 3 4 5 6 7 8 9 1 ...
- Oracle整合Mybatis实现list数据插入时,存在就更新,不存在就插入以及随机抽取一条记录
作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 目录 Oracle整合Mybatis实现list数据插入时,存在就更新,不存在就插入 entity 对应表中字段,如不对应,在xml中起别名 map ...
- 【转】oracle 中随机取一条记录的两种方法
oracle 中随机取一条记录的两种方法 V_COUNT INT:=0; V_NUM INT :=0; 1:TBL_MYTABLE 表中要有一个值连续且唯一的列FID BEGIN SELECT COU ...
- mysql 查询一条记录的下一条和上一条记录
如果ID是主键或者有索引,可以直接查找: 方法一: 查询上一条记录的SQL语句(如果有其他的查询条件记得加上other_conditions以免出现不必要的错误): select * from tab ...
随机推荐
- 用css画的一个图形 空心正方形+四边四色
div{ width: 100px; height: 100px; border: 100px solid black; border-left-color:darkcyan; border-righ ...
- Ubuntu下添加Python环境变量
最近把自己在windows上的Django项目放在的Ubuntu上,启动时提示找不到模块 原来是自己的项目用的是虚拟环境,安装的第三方库全部在虚拟环境中 AutoTestSite/venv/Lib/s ...
- 以太坊系列之十一: 零起步使用remix开发智能合约
一步一步使用remix开发智能合约 最新版的remix(2017-8-3)只能使用在线开发了,已经没有离线版本了,并且好像在线版本要FQ才能访问(自行解决). 1.打开remix 注意地址如果是htt ...
- 趣图:快下班了,剩一个bug,修复一下再走
趣图:当我给老板展示我修复了那个 bug 时 趣图:当我以为这是最后一个Bug时……
- OOP3(继承中的类作用域/构造函数与拷贝控制/继承与容器)
当存在继承关系时,派生类的作用域嵌套在其基类的作用域之内.如果一个名字在派生类的作用域内无法正确解析,则编译器将继续在外层的基类作用域中寻找该名字的定义 在编译时进行名字查找: 一个对象.引用或指针的 ...
- 洛谷P4207 [NOI2005]月下柠檬树(计算几何+自适应Simpson法)
题面 传送门 题解 我还好奇自适应辛普森法干嘛用的呢--突然想起来积分的一个用处就是求曲边图形的面积-- 我们先来考虑一下这些投影是什么形状 一个圆的投影还是它自己 一个圆锥的投影是一个圆加上一个点, ...
- 基于Solr的多表join查询加速方法
前言 DT时代对平台或商家来说最有价值的就是数据了,在大数据时代数据呈现出数据量大,数据的维度多的特点,用户会使用多维度随意组合条件快速召回数据.数据处理业务场景需要实时性,需要能够快速精准的获得到需 ...
- Github 三种克隆模式
1.我称为平常模式,用于项目的本地克隆使用.(无权限.无加密.ssh protocol) git clone http://github.com/username/exampleproject 2.我 ...
- MyBatis配置文件的配置说明
Properties 1.创建一个资源文件jdbc.properties: jdbc.driverClassName=oracle.jdbc.driver.OracleDriver jdbc.url= ...
- .net core UseHttpsRedirection() 正式环境无效
莫名其妙遇到这样的问题.这样的配置在本地可以,正式环境就不行了. ··· public void Configure(IApplicationBuilder app, Microsoft.AspNet ...