我使用MongoDB和Mongoose作为我的ODM,并且我尝试在同一语句中使用populate
和group by
进行查询。
这是我的简单文档模型:
var userSchema = new Schema({
username: String
});
var messageSchema = new Schema({
from: { type: Schema.ObjectId, ref: 'User' },
to: { type: Schema.ObjectId, ref: 'User' },
message: String,
date: { type: Date, default: Date.now }
});
我只是试图为每个用户收集每条消息,并与他谈话的每个用户进行分组。我试过这样:
this.find({ 'to': user })
.sort({ 'date': 1 })
.group('from')
.populate(['from', 'to'])
.exec(callback);
但是,不幸的是,我的模型没有group
方法。你有什么解决办法吗?
谢谢。
答案 0 :(得分:18)
使用$ lookup populate的示例,lookup填充为数组,因此$ unwind。
Option Explicit
Sub insertCheckboxes()
Dim myBox As CheckBox
Dim myCell As Range
Dim cellRange As String
Dim cboxLabel As String
Dim linkedColumn As String
cellRange = InputBox(Prompt:="Cell Range", _
Title:="Cell Range")
linkedColumn = InputBox(Prompt:="Linked Column", _
Title:="Linked Column")
cboxLabel = InputBox(Prompt:="Checkbox Label", _
Title:="Checkbox Label")
With ActiveSheet
For Each myCell In .Range(cellRange).Cells
With myCell
Set myBox = .Parent.CheckBoxes.Add(Top:=.Top, _
Width:=.Width, Left:=.Left, Height:=.Height)
With myBox
.LinkedCell = linkedColumn & myCell.Row
.Caption = cboxLabel
.Name = "checkbox_" & myCell.Address(0, 0)
End With
.NumberFormat = ";;;"
End With
Next myCell
End With
End Sub
答案 1 :(得分:11)
这里使用的更好选项是.aggregate()
,这是一个本机代码实现,与使用JavaScript引擎处理结果的MongoDB的.group()
方法不同。
虽然不直接支持像.populate()
这样的方法,但这是设计的,因为聚合管道和其他方法不会严格返回基于当前模型架构的响应。由于“假设”是你正在做的事情是错误的,它只是一个原始对象响应。
然而,没有什么可以阻止您将响应“转换”为mongoose文档,然后使用所需路径调用.populate()
的模型形式:
Message.aggregate(
[
{ "$match": { "to": user } },
{ "$sort": { "date": 1 } },
{ "$group": {
"_id": "from",
"to": { "$first": "$to" },
"message": { "$first": "$message" },
"date": { "$first": "$date" },
"origId": { "$first": "$_id" }
}}
],
function(err,results) {
if (err) throw err;
results = result.map(function(doc) {
doc.from = doc._id
doc._id = doc.origId;
delete doc.origId;
return new Message( doc )
});
User.populate( results, { "path": "from to" }, function(err,results) {
if (err) throw err;
console.log( JSON.stringify( results, undefined, 4 ) );
});
}
)
当然,这只是真正从运营商隐含的每个“来自”返回$first
消息。
或许你所谓的“分组”实际意味着“排序”:
Message.find({ "to": user })
.sort({ "from": 1, "date": 1 })
.populate("from to")
.exec(function(err,messsages) {
if (err) throw err;
console.log( JSON.stringify( messages, undefined, 4 ) );
});
由于您的上下文显示“所有消息”,而不是分组运算符暗示的内容,例如.aggregate()
或.group()
集合方法。因此,消息通过排序“组合在一起”,而不是任何特定的分组。
后者听起来就像你真正想要的那样,但如果你真的打算真正“分组”,那么就会有聚合示例以及如何使用.populate()
。
答案 2 :(得分:0)
这是我按单元类型对单元进行分组的方式
分组之前
[
{
"_id": "5f68d604d47d3517ac3f00a1",
"active": true,
"unitName": "3",
"unitType": [
{
"_id": "5f5b0a20c546f803d36f43b2",
"active": true,
"facilities": [
"5f5b0977c546f803d36f43b0",
"5f5b096ac546f803d36f43ae"
],
"typeName": "Deluxe Room",
"numberOfBeds": 2,
"rate": 15000,
"__v": 0
}
],
"status": "CLEANING",
"createdAt": "2020-09-21T16:34:12.189Z",
"__v": 0
},
{
"_id": "5f6adb612bf2c33614d9d28e",
"active": true,
"unitName": "1",
"unitType": [
{
"_id": "5f5b0a20c546f803d36f43b2",
"active": true,
"facilities": [
"5f5b0977c546f803d36f43b0",
"5f5b096ac546f803d36f43ae"
],
"typeName": "Deluxe Room",
"numberOfBeds": 2,
"rate": 15000,
"__v": 0
}
],
"status": "READY",
"createdAt": "2020-09-23T05:21:37.746Z",
"__v": 0
}]
汇总
Unit.aggregate([
{
$match:{
_id : {
$nin : reservedUnits
}
}
},
{
$lookup: {
from: 'unittypes',
localField: 'unitType',
foreignField: '_id',
as: 'unitType'
}
},
{
$project: {
unitType: {
createdAt: 0
}
}
},
{$group : {_id : "$unitType", units: { $push: "$$ROOT" }}},
{
$project: {
_id : {
facilities: 0
},
units: {
unitType: 0
}
}
},
]);
结果
[
{
"_id": [
{
"_id": "5f5b0a20c546f803d36f43b2",
"active": true,
"typeName": "Deluxe Room",
"numberOfBeds": 2,
"rate": 15000,
"__v": 0
}
],
"units": [
{
"_id": "5f68d604d47d3517ac3f00a1",
"active": true,
"unitName": "3",
"status": "CLEANING",
"createdAt": "2020-09-21T16:34:12.189Z",
"__v": 0
},
{
"_id": "5f6adb612bf2c33614d9d28e",
"active": true,
"unitName": "1",
"status": "READY",
"createdAt": "2020-09-23T05:21:37.746Z",
"__v": 0
}
]
}]