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 ...
随机推荐
- Header Only Library
什么是Header Only Library Header Only Library把一个库的内容完全写在头文件中,不带任何cpp文件. 这是一个巧合,决不是C++的原始设计. 第一次这么做估计是ST ...
- tomcat的内存配置,关于-Xms -Xmx -XX:PermSize -XX:MaxPermSize的理解和区别
JVM按照其存储数据的内容将所需内存分配为堆区与非堆区两个部分:所谓堆区即为通过new的方式创建的对象(类实例)所占用的内存空间:非堆区即为代码.常量.外部访问(如文件访问流所占资源)等.然而虽然ja ...
- C# 筛选string 类型里面的汉字,获取首字母字母,正则表达式Regex 常用验证
界面效果 1.提取汉字 private void buttonX1_Click(object sender, EventArgs e) { if (TxtYuan.Text.Trim() != &qu ...
- Nexus 私有仓库
Nexus3.6和Nexus2.x安装不同,2.x版本需要安装服务,再启动.而3.6版本则更加简单. 步骤如下: jdk环境:1.8 Nexus3.6解压(注意,路径不要带空格及中文),解压后有两个文 ...
- NSCache 缓存
前言 NSCache 是苹果提供的一个专门用来做缓存的类,当内存 "不足" 或超过限制的时候,会自动清理缓存,使用时可以指定缓存的数量和成本. 用法与 NSMutableDicti ...
- Docker安装FastDFS
什么是FastDFS? FastDFS 是用 c 语言编写的一款开源的分布式文件系统.FastDFS 为互联网量身定制, 充分考虑了冗余备份.负载均衡.线性扩容等机制,并注重高可用.高性能等指标,使用 ...
- UML之类图详解
原文链接:https://www.cnblogs.com/xsyblogs/p/3404202.html 我们通过一个示例来了解UML类图的基本语法结构.画UML类图其实有专业的工具,像常用的Visi ...
- iframe里面的元素触发父窗口元素事件的jquery代码 转
例如父窗口定义了一个事件. top: $(dom1).bind('topEvent', function(){}); 那么iframe里面的元素怎样触发父窗口dom1的事件呢?这样吗? $(dom1, ...
- Jupyter Notebook 使用入门
Jupyter Notebook 简介与安装 Jupyter Notebook 是一款开放源代码的 Web 应用程序,可让我们创建并共享代码和文档. 它提供了一个环境,你可以在其中记录代码,运行代码, ...
- 12.谈谈this对象的理解
1.谈谈this对象的理解? 2.this指向问题 Javascript理解this对象 this是函数运行时自动生成的一个内部对象,只能在函数内部使用,但总指向调用它的对象. 通过以下几个例子加 ...