我在如何最好地在mongoose中实现此连接/查询时遇到了一些麻烦。
var mongoose = require('mongoose');
var addressSchema = new mongoose.Schema{
rank: Number,
address: String,
tag_name: String,
tag_url: String};
var tagSchema = new mongoose.Schema{
address: String,
name: String,
url: String};
我保存了一堆地址并保存了一堆标签。有些地址有标签,大部分都没有。我经常单独更新地址和标签。我想要做的是查询一些特定的地址并将它们作为一个数组返回,并填入标记字段(地址标记字段在数据库中为空)。
因此,例如,我想在不为每个地址进行db查询的情况下执行此操作(示例中为101 db查询)。我不确定$ match或$ in或populate是否是我正在寻找的。以下代码未经测试,可能无效,但它应该让您了解我正在尝试做什么。
var db = require('../config/dbschema');
// find an array of addresses
db.addressModel.find({ rank: { $lte: 100 } }, function(err, addresses) {
// now fill in the tag fields and print
addTagField(0, addresses);
});
// recursive function to fill in tag fields
// address tag name and tag url fields are blank in the database
function addTagField(n, addresses) {
if(n < addresses.length) {
db.tagModel.find( { address: addresses[n].address }, function(err, tag) {
// if find a tag with this address, fill in the fields
// otherwise leave blank and check next address in array
if(tag) {
addresses[n].tag_name = tag.name;
addresses[n].tag_url = tag.url;
}
addTagField(n+1, addresses);
});
} else {
console.log(addresses);
}
}
http://mongoosejs.com/docs/api.html#aggregate_Aggregate-match http://mongoosejs.com/docs/api.html#query_Query-in http://mongoosejs.com/docs/api.html#document_Document-populate
我想用更少的数据库查询来完成上述操作。
答案 0 :(得分:1)
你的主要问题是你没有利用Mongoose的关系映射。稍微改变您的模式,您的问题将很容易解决。你可以这样做:
var tagSchema = new Schema({
name: String,
url: String,
})
var addressSchema = new Schema ({
rank: Number,
address: String,
tags: [tagSchema],
})
addressModel.find({rank: {$lte: 100}}, function(err, addresses) {
...
})
或者这个:
var tagSchema = new Schema({
name: String,
url: String,
})
var addressSchema = new Schema ({
rank: Number,
address: String,
tags: [{type: ObjectId, ref: 'Tag'}],
})
addressModel
.find({rank: {$lte: 100}})
.populate('tags', 'name url')
.exec(function(err, addresses) {
...
})
答案 1 :(得分:0)
我不想嵌入文档。这就是我想出来的。
db.addressModel.find({ rank: { $lte: 100 } }, function(err, addresses) {
if(err) return res.send(400);
if(!addresses) return res.send(404);
var addrOnlyAry = addresses.map(function(val, idx) { return val.address; });
db.tagModel.find( { address: { $in: addrOnlyAry } }, {}, function(err, tags) {
if(err) return res.send(400);
if(tags.length > 0) addresses = setTagFields(addresses, tags);
return res.json(addresses);
}
}
function setTagFields(addresses, tags) {
for(var i=0; i < tags.length; i++) {
for(var j=0; j < addresses.length; j++) {
if(addresses[j].address === tags[i].address) {
addresses[j].tag_name = tags[i].tag;
addresses[j].tag_url = tags[i].url;
break;
}
}
}
return addresses;
}