Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/34.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Node.js MongoDB按非索引字段排序的最佳实践_Node.js_Mongodb_Sorting_Meteor - Fatal编程技术网

Node.js MongoDB按非索引字段排序的最佳实践

Node.js MongoDB按非索引字段排序的最佳实践,node.js,mongodb,sorting,meteor,Node.js,Mongodb,Sorting,Meteor,我有一个应用程序,允许用户使用自己的自定义数据,所以我不知道数据是什么。但是,我确实希望允许他们对数据进行排序。 这可能是大量的数据,mongodb最终给了我内存错误(32MB限制) 最好的方法是什么?如何允许用户按未知字段对大量数据进行排序 MongoDB允许您以这样一种方式设计模式:它可以在模式中存储对象和对象关系,因此您可以允许用户存储任何类型的信息。正如@kevinadi所说,有32MB的限制。就排序而言,它可以在服务器端完成 这是我在MongoDB和Mongoose ORM中存储对象时

我有一个应用程序,允许用户使用自己的自定义数据,所以我不知道数据是什么。但是,我确实希望允许他们对数据进行排序。 这可能是大量的数据,mongodb最终给了我内存错误(32MB限制)


最好的方法是什么?如何允许用户按未知字段对大量数据进行排序

MongoDB允许您以这样一种方式设计模式:它可以在模式中存储对象和对象关系,因此您可以允许用户存储任何类型的信息。正如@kevinadi所说,有32MB的限制。就排序而言,它可以在服务器端完成

这是我在MongoDB和Mongoose ORM中存储对象时尝试的一个示例

var mongoose = require("mongoose");
var userSchema = new mongoose.Schema({
  email: {
    type: String,
    unique: true,
    required: true,
    lowercase: true,
    trim: true,
    match: [/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, "Please fill a valid email address"]
  },
  custInfo:{
  type:Object,
  required: true
  }
  isConfirmed: {
    type: Boolean,
    required: true,
    default: false
  },
  confirmedOn:{
    type: Date,
    required: true,
    default: Date.now()
  }
});

module.exports = mongoose.model("user",userSchema);

既然您已经标记了这个问题Meteor,我想您就有了默认的Meteor环境,在这里您可以使用客户端轻量级

这使您有机会发布(发布)/返回(方法)大部分未排序的数据,并让客户机处理此任务

试想一下:只有100个客户端要求发布一个每次排序操作都会更新的发布(因为订阅参数会更改,所以发布也会更改)

这已经导致服务器消耗大量RAM,以使观察器(OPLOG等)运行100个发布,每个发布查询大量文档

可能的性能解决方案如下所述。请记住,它们不受任何前端的约束,而是一个概念描述。根据您的前端环境,您必须包括反应性等

选项A-未排序发布,让客户端排序 服务器

客户

const handle=Meteor.subscribe('hugeData'))
if(handle.ready()){
const sortedData=MyCollection.find({…},{sort:{someField:-1})
}
这里有一个很大的优点,如果使用,您可以通知客户完整性状态

请注意,如果要向后扫描(返回文档,使用最新文档),可以使用
提示

Meteor.publish('hugeData',函数(){ 返回MyCollection.find({…},{提示:{$natural:-1}) }) 这比
{sort:{fieldName:-1}}
更有效

选项B-返回未排序的from方法,让客户端排序 现在解决方案a可能仍然存在问题,因为如果有很多订户,它仍然需要消耗大量的RAM。另一种选择(特别是如果实时数据更改不那么相关)是使用Meteor方法:

服务器

Meteor.method('hugeData',函数(){ 返回MyCollection.find({…}).fetch() }) 请注意,这需要向文档发送消息,否则将抛出
未处理的PromiserRejection

客户

这需要客户端上的
LocalCollection
,即与服务器端集合不同步,否则将出现文档同步问题:

const HugeData=new LocalCollection(null)//注意null作为集合名称!
const insertUpdate=文档=>{
if(LocalCollection.findOne(document.\u id)){
删除文档。\u id
返回LocalCollection.update(document.\u id,document)
}否则{
返回LocalCollection.insert(文档)
}
}
Meteor.call('hudeData',(错误,数据)=>{
数据。forEach(插入更新)
})
然后,您可以在客户端上使用
LocalCollection
对接收到的数据进行任何投影


总而言之,将负载移动到客户端是一个很好的折衷办法。只要您在投影需要一段时间时通知他们,就应该可以了。

我目前的想法是添加一个包含1.entity id、2个字段名称和3.field value的索引集合。
将该集合编入索引,然后从中提取有序的实体ID,稍后按ID加载完整的相关文档。

没有关于无索引排序的最佳实践。内存排序在MongoDB端限制为32MB的RAM,因此我可以想到两个备选方案:1)在应用程序中进行排序,2)设计模式,以便t你可以有一个可以排序的索引。否则,32MB的限制最终会影响你。@kevinadi有没有关于DB设计的想法?谢谢你的回答,但似乎客户在大约2000条记录之后不知所措(这是在一台强大的机器上)。是否
被淹没
意味着内存、文档异步移位、cpu峰值或冻结?速度太慢了
Meteor.publish('hugeData', function () {
  return MyCollection.find({ ...})
})