MongoDB – 查询难题 – 文档参考或子文档

我遇到了一些有关我存储在MongoDB中的数据的问题(注意:我使用mongoose作为ODM)。 我有两个模式:

mongoose.model('Buyer',{ credit: Number, }) 

 mongoose.model('Item',{ bid: Number, location: { type: [Number], index: '2d' } }) 

买方/物品将具有父母/子女关系,并具有一对多的关系。 我知道,我可以将项目设置为embedded的子文档到买方文档, 或者我可以创build两个单独的文档与对象ID引用到对方。

我面临的问题是,我需要查询出价低于买家信用的项目 ,以及哪里的地理位置接近某个地理坐标

为了满足第一个标准,似乎我应该embedded项目作为一个subdoc,以便我可以比较这两个数字。 但是,为了比较地理位置与一个geoNear查询,似乎分开文件会更好,否则,我不能在每个子文档上执行geoNear。

有什么办法可以对这些数据执行这两个任务吗? 如果是这样,我应该如何构build我的数据? 如果没有,有没有办法,我可以执行一个查询,然后对第一个查询结果第二个查询?

谢谢你的帮助!

除了embedded和规范化之外,还有另外一个选项用于在mongodb中存储层次结构,即将它们存储为树结构 。 在这种情况下,您可以将买方和项目存储在单独的文档中,但存储在同一个集合中 每个项目文件将需要一个指向其买方(父)文件的字段,并且每个买方文件的父项字段将被设置为空。 我链接的文档解释了几种可以select的实现。

如果你的项目被存储在两个单独的集合中,最好的select将会写你自己的函数,并使用mongoose.connection.db.eval('some code...');来调用它mongoose.connection.db.eval('some code...'); 。 在这种情况下,您可以在服务器端执行高级逻辑。

你可以写这样的东西:

 var allNearItems = db.Items.find( { location: { $near: { $geometry: { type: "Point" , coordinates: [ <longitude> , <latitude> ] }, $maxDistance: 100 } } }); var res = []; allNearItems.forEach(function(item){ var buyer = db.Buyers.find({ id: item.buyerId })[0]; if (!buyer) continue; if (item.bid < buyer.credit) { res.push(item.id); } }); return res; 

经过评估(将其放在mongoose.connection.db.eval("...")调用中),您将获得项目ID的数组。

谨慎使用它。 如果你的allNearItems数组太大,或者你会经常查询,你可以面对性能问题。 MongoDB团队实际上已经不赞成使用直接的js代码执行,但在当前的稳定版本上仍然可用。