MongoDB – 删除唯一文档

huangapple go评论79阅读模式
英文:

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: &quot;$itemId&quot;,
count: {
$count: {}
}
}
},
//  remove those who have count &lt; 2 (unique elements)
{
$match: {
&quot;count&quot;: {
$gte: 2
},
}
},
// populate documents
{
$lookup: {
from: &quot;collection&quot;,
localField: &quot;_id&quot;,
foreignField: &quot;itemId&quot;,
as: &quot;fromItems&quot;
}
},
// level up &#39;fromItems&#39;
{
$unwind: &quot;$fromItems&quot;
},
{
$replaceRoot: {
newRoot: &quot;$fromItems&quot;
}
}
])

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.

huangapple
  • 本文由 发表于 2023年6月19日 19:55:43
  • 转载请务必保留本文链接:https://go.coder-hub.com/76506375.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定