英文:
MongoDB - aggregate match field from the previously matched document
问题
我有一个具有以下架构的集合 -
const ContentSchema = new Schema({
label: {
type: String
},
itemId: {
type: Schema.ObjectId,
refPath: 'onModel'
},
formId: {
type: Schema.ObjectId,
refPath: 'onModel'
},
value: {
type: Schema.Types.Mixed,
index: "text"
},
}, { timestamps: true, versionKey: false });
以下是该集合可能包含的一些示例文档 -
{
_id: ObjectId('647b1538c29a553ad6e8f316'),
label: "Name",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "ABC"
},
{
_id: ObjectId('647b1538c29a553ad6e8f416'),
label: "Email",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "def@mail.com"
},
{
_id: ObjectId('647b1538c29a553ad6e8f516'),
label: "Name",
itemId: ObjectId('647b1538c29a553ad6e8f320'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "MNO"
},
{
_id: ObjectId('647b1538c29a553ad6e8f616'),
label: "Email",
itemId: ObjectId('647b1538c29a553ad6e8f320'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "xyz@mail.com"
}
现在,我需要执行一个查询来从具有formId
为ObjectId('647b1538c29a553ad6e8f913')
的集合中搜索"ABC"。
以下是执行此操作的代码 -
return await ContentModel.aggregate([
{
$match: {
$text: { $search: text },
formId: new mongoose.Types.ObjectId(formId)
}
}]
上面的代码完全正常工作,并返回文档 -
{
_id: ObjectId('647b1538c29a553ad6e8f316'),
label: "Name",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "ABC"
}
但我需要在同一聚合中获取更多记录。现在我需要查找具有itemId为ObjectId('647b1538c29a553ad6e8f313')
的文档中的其他文档。
因此,聚合现在应该返回2个文档 -
{
_id: ObjectId('647b1538c29a553ad6e8f316'),
label: "Name",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "ABC"
},
{
_id: ObjectId('647b1538c29a553ad6e8f416'),
label: "Email",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "def@mail.com"
}
我尝试使用以下查询,但不起作用 -
return await ContentModel.aggregate([
{
$match: {
$text: { $search: text },
formId: new mongoose.Types.ObjectId(formId)
}
},
{
$match: { itemId: "$itemId" }
}]
英文:
I have a collection with following schema -
const ContentSchema = new Schema({
label: {
type: String
},
itemId: {
type: Schema.ObjectId,
refPath: 'onModel'
},
formId: {
type: Schema.ObjectId,
refPath: 'onModel'
},
value: {
type: Schema.Types.Mixed,
index: "text"
},
}, { timestamps: true, versionKey: false });
Here are some example documents the collection may have -
{
_id: ObjectId('647b1538c29a553ad6e8f316'),
label: "Name",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "ABC"
},
{
_id: ObjectId('647b1538c29a553ad6e8f416'),
label: "Email",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "def@mail.com"
},
{
_id: ObjectId('647b1538c29a553ad6e8f516'),
label: "Name",
itemId: ObjectId('647b1538c29a553ad6e8f320'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "MNO"
},
{
_id: ObjectId('647b1538c29a553ad6e8f616'),
label: "Email",
itemId: ObjectId('647b1538c29a553ad6e8f320'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "xyz@mail.com"
}
Now, I need to perform a query to search "ABC" from the collection with formId
- ObjectId('647b1538c29a553ad6e8f913')
.
Here is the code to do that -
return await ContentModel.aggregate([
{
$match: {
$text: { $search: text },
formId: new mongoose.Types.ObjectId(formId)
}
}]
The above code is absolutely working fine and returns the document -
{
_id: ObjectId('647b1538c29a553ad6e8f316'),
label: "Name",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "ABC"
}
But I need more records within the same aggregation. Now I need to find out other documents from the document with itemId - ObjectId('647b1538c29a553ad6e8f313')
.
So that the aggregation should now return 2 documents -
{
_id: ObjectId('647b1538c29a553ad6e8f316'),
label: "Name",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "ABC"
},
{
_id: ObjectId('647b1538c29a553ad6e8f416'),
label: "Email",
itemId: ObjectId('647b1538c29a553ad6e8f313'),
formId: ObjectId('647b1538c29a553ad6e8f913'),
value: "def@mail.com"
}
I am trying with following query which does not work -
return await ContentModel.aggregate([
{
$match: {
$text: { $search: text },
formId: new mongoose.Types.ObjectId(formId)
}
},
{
$match: { itemId: "$itemId" }
}]
答案1
得分: 0
如果我理解正确,您可以按以下方式在自己的集合中使用 $lookup
:
在这个查询中,您可以像您已经做的那样使用 $match
,然后使用匹配的结果进行 $lookup
(类似于 SQL 中的 JOIN
),针对您的数据使用 collection
和匹配的 itemId
。
所以就像是说“将匹配的 itemId
与所有其他 itemId
进行关联”。我认为这就是您想要的。
db.collection.aggregate([
{
"$match": { /* 您的匹配条件 */ }
},
{
"$lookup": {
"from": "collection",
"localField": "itemId",
"foreignField": "itemId",
"as": "results"
}
},
{
"$unwind": "$results"
},
{
"$replaceRoot": {
"newRoot": "$results"
}
}
])
此外,另外两个步骤是将结果输出为根。
示例在这里。
英文:
If I've understood correctly you can use $lookup
with your own collection in this way:
In this query you can $match
as you have done and then, with matching results you can $lookup
(like a SQL JOIN
) against your data using collection
and matching itemId
.
So is like to say "join the matching itemId
with all others itemId
". And I think is what you want.
db.collection.aggregate([
{
"$match": { /* your match*/ }
},
{
"$lookup": {
"from": "collection",
"localField": "itemId",
"foreignField": "itemId",
"as": "results"
}
},
{
"$unwind": "$results"
},
{
"$replaceRoot": {
"newRoot": "$results"
}
}
])
Also the two others steps are to output the result as root.
Example here
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论