MongoDB $查找与有条件的外国人

发布于 2025-01-27 19:37:08 字数 1863 浏览 1 评论 0原文

游乐场: https://mongoplayground.net/p/oxmnscfzpmq

我的mongodb版本:4.2。

我有一个集合car_parts客户。 顾名思义,car_parts具有汽车零件,其中一些可以具有字段sub_parts,这是car_parts._idss._id s s此部分由。

每个购买东西的客户都存储在客户中。 零件客户的字段包含客户在特定日期一起购买的零件列表。

我想在MongoDB中有一个汇总查询,该查询返回了购买哪个汽车零件的映射(fuild_parts),从中cansuse。但是,如果car_parts具有字段sub_parts,则客户应仅显示子部分。

因此,除sub_parts主题外,操场上的查询几乎给出了正确的结果。

customer_3的示例:

{
      "_id": "customer_3",
      "parts": [
        {
          "bought_parts": [
            3
          ],
          date: "15.07.2020"
        }
      ]
   }

因为购买了_parts car_parts._id = 3:

{
      "_id": 3,
      "name": "steering wheel",
      "sub_parts": [
        1, // other car_parts._id s
        2
      ]
 }

结果应显示Customer_3作为CAR Parts 1和2的客户。 我不确定如何完成此操作,但是我假设使用实际ID [1,2]可以解决它的“临时”替换ID 3 购买的_parts

预期输出:

[
  {
    "_id": 1,
    "customers": [
      "customer_1",
      "customer_2",
      "customer_3"  // <- since customer_3 bought car part 3 which has 1 in sub_parts
    ]
  },
  {
    "_id": 2,
    "customers": [
     "customer_3"  // <- since customer_3 bought car part 3 which has 2 in sub_parts
    ]
  },
  {
    "_id": 3,
    "customers": [
      "customer_1", // <- since car_parts.id = 3 has [1, 2] in sub_parts, show customers of ids [1, 2]
      "customer_2",
      "customer_3"
    ]
  },
  {
    "_id": 4,
    "customers": [
      "customer_1",
      "customer_2"
    ]
  }
]

非常感谢!

Playground: https://mongoplayground.net/p/OxMnsCFZpmQ

My MongoDB version: 4.2.

I have a collection car_parts and customers.
As the name suggests car_parts has car parts, where some of them can have a field sub_parts which is a list of car_parts._ids this part consists of.

Every customer that bought something at us is stored in customers. The parts field for a customer contains a list of parts the customer bought together on a certain date.

I would like to have an aggregate query in MongoDB that returns a mapping of which car parts were bought (bought_parts) from which customers. However, if the car_parts has the field sub_parts, the customer should show up for the subparts only.

So the query in the playground gives almost the correct result already, except for the sub_parts topic.

Example for customer_3:

{
      "_id": "customer_3",
      "parts": [
        {
          "bought_parts": [
            3
          ],
          date: "15.07.2020"
        }
      ]
   }

Since bought_parts has car_parts._id = 3:

{
      "_id": 3,
      "name": "steering wheel",
      "sub_parts": [
        1, // other car_parts._id s
        2
      ]
 }

The result should show customer_3 as a customer of car parts 1 and 2.
I'm not sure how to accomplish this, but I assume a "temporary" replacement of the id 3 in bought_parts with the actual ids [1,2] might solve it.

Expected output:

[
  {
    "_id": 1,
    "customers": [
      "customer_1",
      "customer_2",
      "customer_3"  // <- since customer_3 bought car part 3 which has 1 in sub_parts
    ]
  },
  {
    "_id": 2,
    "customers": [
     "customer_3"  // <- since customer_3 bought car part 3 which has 2 in sub_parts
    ]
  },
  {
    "_id": 3,
    "customers": [
      "customer_1", // <- since car_parts.id = 3 has [1, 2] in sub_parts, show customers of ids [1, 2]
      "customer_2",
      "customer_3"
    ]
  },
  {
    "_id": 4,
    "customers": [
      "customer_1",
      "customer_2"
    ]
  }
]

Thanks a lot in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

梦回旧景 2025-02-03 19:37:08

编辑:一种做法的方法是:

db.car_parts.aggregate([
  {
    $project: {
      topLevel: {$concatArrays: [{$ifNull: ["$sub_parts", []]}, ["$_id"]]},
      sub_parts: 1
    }
  },
  {$unwind: "$topLevel"},
  {
    $group: {
      _id: "$topLevel",
      parts: {$push: "$_id"},
      sub_parts: {$first: "$sub_parts"}
    }
  },
  {
    $project: {
      parts: {$concatArrays: [{"$ifNull": ["$sub_parts", []]}, "$parts"]}
    }
  },
  {
    $lookup: {
      from: "customers",
      localField: "parts",
      foreignField: "parts.scanned_parts",
      as: "customers"
    }
  },
  {$project: {customers: "$customers._id"}}
])

如您所见,在

由于您说只有一个子部分,所以我使用了另一个想法:在$ lookup之前创建一个顶级。由于您希望使用第3部分的客户,例如,根据第3部分的第1部分进行注册,其想法是将其分组。在$查找之后,此连接有点笨拙,但是如果我们在car_parts Collection上使用$ lookup,实际上,我们已经知道零件1,2是3个子部分。创建toplevel临时字段,允许事先将所有零件和子部分分组,如果客户使用的客户使用,则他应该在此顶级部分下注册。这使事情变得更加优雅...

EDIT: One way to do it is:

db.car_parts.aggregate([
  {
    $project: {
      topLevel: {$concatArrays: [{$ifNull: ["$sub_parts", []]}, ["$_id"]]},
      sub_parts: 1
    }
  },
  {$unwind: "$topLevel"},
  {
    $group: {
      _id: "$topLevel",
      parts: {$push: "$_id"},
      sub_parts: {$first: "$sub_parts"}
    }
  },
  {
    $project: {
      parts: {$concatArrays: [{"$ifNull": ["$sub_parts", []]}, "$parts"]}
    }
  },
  {
    $lookup: {
      from: "customers",
      localField: "parts",
      foreignField: "parts.scanned_parts",
      as: "customers"
    }
  },
  {$project: {customers: "$customers._id"}}
])

As you can see working on this playground.

Since you said there is only one level of sub-parts, I used another idea: creating a top level before the $lookup. Since you want customers that used part 3 for example, to be registered under parts 1,2 which are sub-parts of 3, the idea is to group them. This connection is a bit clumsy after the $lookup, but if we use the data that we have on the car_parts collection before the $lookup, we actually knows already that parts 1,2 are subpart of 3. Creating a topLevel temporary field, allows to group, in advance, all the parts and sub-parts that if a customer used on of them, he should be registered under this top level part. This makes things much more elegant...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文