我有以下mongoose架构:
const userSchema = new mongoose.Schema({
email: { type: String, unique: true },
fragments: [{type: mongoose.Schema.Types.ObjectId, ref: 'Fragment'}]
}, { timestamps: true, collection: 'user' });
和
const fragmentSchema = new mongoose.Schema({
text: String,
owner: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
}, { timestamps: true, collection: 'fragment' });
在数据中,我在Fragment
中有引用,但在User
中没有引用:
用户:
{
"_id" : ObjectId("58373e571cbccb010012bfcd"),
"email" : "email@example.com",
// no "fragments": [ObjectId('58075ce37b7f2f01002b718f')] etc.
}
片段:
{
"_id" : ObjectId("58075ce37b7f2f01002b718f"),
"text" : "Donc, il faut changer de méthode",
"owner" : ObjectId("58075ce27b7f2f01002b717f")
}
我想查询按片段数量排序的用户,我无法实现这一点......
首先,我想做这项工作:
User.find({_id: '58075ce27b7f2f01002b717f'})
.populate('fragments').exec(console.log)
返回
{
_id: 58075ce27b7f2f01002b717f,
email: 'bububg@hotmail.fr',
fragments: []
}
虽然我至少应该包含上述fragment
。
关于排序查询,这是我现在的位置:
User.aggregate([
{ "$project": {
"email": 1,
"fragments": 1,
"nbFragments": { "$size": { "$ifNull": [ "$fragments", [] ] } }
}},
{ "$sort": { "nbFragments": -1 } }
], console.log)
至少它运行,但所有nbFragments
字段都设置为0.这可能与.populate('fragments')
不起作用的事实有关,但我无法确定。
感谢您的帮助,我没想到使用Mongodb会有这么多麻烦...
编辑:感谢@Veeram,遗憾的是你的解决方案无效:
User.find({}).find({_id: '58075ce27b7f2f01002b717f'}).populate('fragments').exec(console.log)
[ { _id: 58075ce27b7f2f01002b717f,
email: 'email@example.com',
// no fragments entry
} ]
当我更新我的架构时:
userSchema.virtual('fragments', {
ref: 'Fragment',
localField: '_id',
foreignField: 'owner',
options: { sort: { number: 1 }}, // Added sort just as an example
});
关于汇总,用:
User.aggregate([{
$lookup: {
from: 'Fragment',
localField: '_id',
foreignField: 'owner',
as: 'fragments'
}
}, { "$project": {
"email": 1,
"fragments": 1,
"nbFragments": {
"$size": { "$ifNull": [ "$fragments", [] ] } }
}}, { "$sort": { "nbFragments": -1 } }
]).exec(console.log)
我明白了:
{
_id: 58075ce27b7f2f01002b717f,
email: 'email@example.com',
fragments: [] // fragments are always empty while they shouldn't!
}
答案 0 :(得分:0)
使用以下数据进行测试
User:
{
"_id" : ObjectId("58373e571cbccb010012bfcd"),
"email" : "email@example.com"
}
Fragment:
{
"_id" : ObjectId("58075ce37b7f2f01002b718f"),
"text" : "Donc, il faut changer de méthode",
"owner" : ObjectId("58373e571cbccb010012bfcd")
}
响应
[{"_id":"58373e571cbccb010012bfcd","email":"email@example.com","fragments":[{"_id":"58075ce37b7f2f01002b718f","text":"Donc, il faut changer de méthode","owner":"58373e571cbccb010012bfcd"}],"nbFragments":1}]
您定义架构以使用owner
填充fragments
也称为虚拟人口。 http://mongoosejs.com/docs/populate.html
const userSchema = new mongoose.Schema({
email: { type: String, unique: true }
}, { timestamps: true, collection: 'user' });
var User = mongoose.model("User", userSchema);
const fragmentSchema = new mongoose.Schema({
text: String,
owner: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
}, { timestamps: true, collection: 'fragment' });
var Fragment = mongoose.model("Fragment", fragmentSchema);
userSchema.virtual('fragments', {
ref: 'Fragment',
localField: '_id',
foreignField: 'owner',
options: { sort: { text: -1 }}, // Added sort just as an example
});
现在这将按预期工作,但我不知道如何对某些动态字段进行排序,例如猫鼬中片段数量的计数。我不认为这是可能的
User.find({_id: '58373e571cbccb010012bfcd'})
.populate('fragments').exec(function (err, user) {
console.log(JSON.stringify(user));
});
现在好了动态排序,你必须使用$lookup
(相当于populate
)的替代原始mongo查询。
const userSchema = new mongoose.Schema({
email: { type: String, unique: true }
}, { timestamps: true, collection: 'user' });
var User = mongoose.model("User", userSchema);
const fragmentSchema = new mongoose.Schema({
text: String,
owner: {type: mongoose.Schema.Types.ObjectId, ref: 'User'},
}, { timestamps: true, collection: 'fragment' });
User.aggregate([{
$lookup: {
from: 'fragment',
localField: '_id',
foreignField: 'owner',
as: 'fragments'
}
}, { "$project": {
"email": 1,
"fragments": 1,
"nbFragments": {
"$size": { "$ifNull": [ "$fragments", [] ] } }
}}, { "$sort": { "nbFragments": -1 } }
]).exec(function (err, user) {
console.log(JSON.stringify(user));
})