英文:
MongoDB - remove unique documents
问题
我需要删除具有字段值唯一的文档。我正在运行一个查询,根据一些条件查找文档。以下是查询 -
db.contents.aggregate([
{
$match: {
$or: [
{
$and: [
{ widgetId: new ObjectId("648d461dae1b9fb2af57fbb2") },
{ value: 'Yes' }
]
},
{
$and: [
{ widgetId: new ObjectId("648d4111ae1b9fb2af57f8f9") },
{
value: "20"
}
]
}
]
}
}
])
在运行查询后,我从contents
集合中获得以下文档 -
[{
_id: ObjectId("648d50d3221f77c425aac162"),
label: 'Featured Product',
itemId: ObjectId("648d50d3221f77c425aac146"),
slug: 'featured-product',
value: 'Yes',
widgetId: ObjectId("648d461dae1b9fb2af57fbb2")
}
{
_id: ObjectId("648d5131221f77c425aac1b9"),
label: 'Featured Product',
itemId: ObjectId("648d5131221f77c425aac1b0"),
slug: 'featured-product',
value: 'Yes',
widgetId: ObjectId("648d461dae1b9fb2af57fbb2")
}
{
_id: ObjectId("648d5199221f77c425aac223"),
label: 'Featured Product',
itemId: ObjectId("648d5199221f77c425aac21a"),
slug: 'featured-product',
value: 'Yes',
widgetId: ObjectId("648d461dae1b9fb2af57fbb2")
}
{
_id: ObjectId("648d51d1221f77c425aac28b"),
label: 'Discount',
itemId: ObjectId("648d51d1221f77c425aac284"),
slug: 'discount',
value: '20',
widgetId: ObjectId("648d4111ae1b9fb2af57f8f9")
}
{
_id: ObjectId("648d51d1221f77c425aac28d"),
label: 'Featured Product',
itemId: ObjectId("648d51d1221f77c425aac284"),
slug: 'featured-product',
value: 'Yes',
widgetId: ObjectId("648d461dae1b9fb2af57fbb2")
}]
现在,在同一个查询中,我需要删除所有具有唯一itemId
的文档。因此,结果输出应该是 -
[{
_id: ObjectId("648d51d1221f77c425aac28b"),
label: 'Discount',
itemId: ObjectId("648d51d1221f77c425aac284"),
slug: 'discount',
value: '20',
widgetId: ObjectId("648d4111ae1b9fb2af57f8f9")
}
{
_id: ObjectId("648d51d1221f77c425aac28d"),
label: 'Featured Product',
itemId: ObjectId("648d51d1221f77c425aac284"),
slug: 'featured-product',
value: 'Yes',
widgetId: ObjectId("648d461dae1b9fb2af57fbb2")
}]
我认为,我需要应用filter
来执行这个任务,但找不到解决方案。可能还有其他方法。
英文:
I need to remove documents those are unique with a field value. I am running a query to find out documents by some conditions. Here is the query -
db.contents.aggregate([
{
$match: {
$or: [
{
$and: [
{ widgetId: new ObjectId("648d461dae1b9fb2af57fbb2") },
{ value: 'Yes' }
]
},
{
$and: [
{ widgetId: new ObjectId("648d4111ae1b9fb2af57f8f9") },
{
value: "20"
}
]
}
]
}
}
])
I get following documents from contents
collection after running the query -
[{
_id: ObjectId("648d50d3221f77c425aac162"),
label: 'Featured Product',
itemId: ObjectId("648d50d3221f77c425aac146"),
slug: 'featured-product',
value: 'Yes',
widgetId: ObjectId("648d461dae1b9fb2af57fbb2")
}
{
_id: ObjectId("648d5131221f77c425aac1b9"),
label: 'Featured Product',
itemId: ObjectId("648d5131221f77c425aac1b0"),
slug: 'featured-product',
value: 'Yes',
widgetId: ObjectId("648d461dae1b9fb2af57fbb2")
}
{
_id: ObjectId("648d5199221f77c425aac223"),
label: 'Featured Product',
itemId: ObjectId("648d5199221f77c425aac21a"),
slug: 'featured-product',
value: 'Yes',
widgetId: ObjectId("648d461dae1b9fb2af57fbb2")
}
{
_id: ObjectId("648d51d1221f77c425aac28b"),
label: 'Discount',
itemId: ObjectId("648d51d1221f77c425aac284"),
slug: 'discount',
value: '20',
widgetId: ObjectId("648d4111ae1b9fb2af57f8f9")
}
{
_id: ObjectId("648d51d1221f77c425aac28d"),
label: 'Featured Product',
itemId: ObjectId("648d51d1221f77c425aac284"),
slug: 'featured-product',
value: 'Yes',
widgetId: ObjectId("648d461dae1b9fb2af57fbb2")
}]
Now, in the same query I need to remove all documents those have unique itemId
. So, the result output should be -
[{
_id: ObjectId("648d51d1221f77c425aac28b"),
label: 'Discount',
itemId: ObjectId("648d51d1221f77c425aac284"),
slug: 'discount',
value: '20',
widgetId: ObjectId("648d4111ae1b9fb2af57f8f9")
}
{
_id: ObjectId("648d51d1221f77c425aac28d"),
label: 'Featured Product',
itemId: ObjectId("648d51d1221f77c425aac284"),
slug: 'featured-product',
value: 'Yes',
widgetId: ObjectId("648d461dae1b9fb2af57fbb2")
}]
I think, I need to apply filter
to perform the task but can't find out a solution. There might be other approaches to that.
答案1
得分: 0
我认为我们可以通过以下查询来实现这个目标:
db.collection.aggregate([
// 基于 itemId 进行分组;
{
$group: {
_id: "$itemId",
count: {
$count: {}
}
}
},
// 删除那些 count < 2 的记录(唯一元素)
{
$match: {
"count": {
$gte: 2
},
}
},
// 填充文档
{
$lookup: {
from: "collection",
localField: "_id",
foreignField: "itemId",
as: "fromItems"
}
},
// 将 'fromItems' 升级为根级文档
{
$unwind: "$fromItems"
},
{
$replaceRoot: {
newRoot: "$fromItems"
}
}
])
以上代码分为三个阶段,
首先,我们对文档进行分组,以观察哪些文档是唯一的。然后我们移除那些文档。
在第二阶段,我们有一组非唯一的文档,但只有它们的 id,我们需要填充它们。因此,我们使用 $lookup
进行自连接。
最后,我们将 fromItems
移到上一级,有效地将其变成一个文档,而不是嵌套文档。
您可以测试一下看看它是否有效。
英文:
I think we might be able to accomplish that by using below query:
db.collection.aggregate([
// grouping based on itemId ;
{
$group: {
_id: "$itemId",
count: {
$count: {}
}
}
},
// remove those who have count < 2 (unique elements)
{
$match: {
"count": {
$gte: 2
},
}
},
// populate documents
{
$lookup: {
from: "collection",
localField: "_id",
foreignField: "itemId",
as: "fromItems"
}
},
// level up 'fromItems'
{
$unwind: "$fromItems"
},
{
$replaceRoot: {
newRoot: "$fromItems"
}
}
])
The above code runs in 3 phases,
First we perform grouping of documents, in order to observe which one of them are unique. We then remove those documents.
In the second phase, we have a collection of non-unique documents but with no data but only their ids, we need to populate them. So, we then perform join on them with itself (using $lookup
).
Finally, we just move fromItems
a level up, effectively making it a document instead of an embedded document.
You can test this out to see if its working or not.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论