[英]MongoDB - Query conundrum - Document refs or subdocument
我将某些数据存储在MongoDB中时遇到了一个问题(注意:我将Mongoose用作ODM)。 我有两种模式:
mongoose.model('Buyer',{
credit: Number,
})
和
mongoose.model('Item',{
bid: Number,
location: { type: [Number], index: '2d' }
})
买方/物品将具有一对多的父子关系。 我知道我可以设置的项目将被嵌入SUBDOCS给买方的文件或我可以创建对象ID引用对方两个单独的文件。
我面临的问题是,我需要查询其出价低于买方信用额度但位置接近某个地理坐标的项目 。
为了满足第一个条件,看来我应该将Items嵌入为子文档,以便可以比较两个数字。 但是,为了将地理位置与geoNear查询进行比较,似乎最好将文档分开,否则,我无法在每个子文档上执行geoNear。
有什么办法可以对这些数据执行两项任务? 如果是这样,我应该如何构造我的数据? 如果没有,是否可以对第一个查询的结果执行一个查询,然后执行第二个查询?
谢谢你的帮助!
还有另一个选项(除了嵌入和规范化之外),用于将层次结构存储在mongodb中,即将它们存储为树结构 。 在这种情况下,您可以将买家和商品存储在单独的文档中,但存储在同一集合中。 每个项目文档都需要一个指向其买方(父)文档的字段,并且每个买方文档的父字段将设置为null。 我链接的文档解释了几种可以选择的实现。
如果您的项目存储在两个单独的集合中,则最好的选择是编写您自己的函数,并使用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代码,但在当前的稳定版本中仍然可用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.