gpt4 book ai didi

mongodb - Mongo : Find documents that have 0 associated documents, 更便宜

转载 作者:行者123 更新时间:2023-12-02 18:01:59 25 4
gpt4 key购买 nike

我有订单商店

db={
"orders": [
{
"_id": 1,
"shop": 1,
"price": 11
},
{
"_id": 2,
"shop": 2,
"price": 101
},

],
"shops": [
{
"_id": 1,

},
{
"_id": 2,

},
{
"_id": 3,

},

],

}

我想找出哪些商店有 0 个订单。

我就是这样做的

db.shops.aggregate([
{
$lookup: {
from: "orders",
let: {
shop: "$_id"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
"$shop",
"$$shop"
]
},

},

},

],
as: "orders",

},

},
{
$project: {
user: "$user",
orderCnt: {
$size: "$orders"
}
}
},
{
$match: {
orderCnt: {
$eq: 0
}
}
},

])

这有效。我也尝试过其他几种方法。但它总是很贵!

如何更高效地找到0订单的店铺?拥有数千个订单和数千个商店,这需要很长时间。

mongo playgound

最佳答案

正如您所提到的,当前的方法您实际上正在使用 $lookup在每个文档上只是为了“不使用”结果,这里有明显的(巨大的)开销,这可以得到很好的优化。

我会选择以下两种解决方案之一:

  1. (我推荐较少但不需要预处理的选项)在 shop 上创建索引order 中的字段如果不存在则集合。现在首先获取所有shop _ids来自order集合,然后在 find 中使用它查询shop收藏:
const shopIds = await mongo.getCollection('orders').distinct('shop');
const shopsWithNoOrders = await mongo.getCollection('shops').find({ _id: {$nin: shopIds }});

这种方法将比您当前的方法快得多,但是它确实存在一些问题,最大的问题是 $nin运算符:

The inequality operator$ninis not very selective since it often matches a large portion of the index. As a result, in many cases, a$ninquery with an index may perform no better than a$ninquery that must scan all documents in a collection. See also Query Selectivity.

基本上性能仍有待提高。

  • 我推荐的解决方案需要进行一些预处理,这需要更改商店架构并添加新字段“activeOrders”,本质上我们将在每个商店上维护一个计数器,用于显示当前有多少订单。
  • 这意味着对于每个订单插入和删除,您都需要更新商店的事件订单,这应该不会太难维护,并且是一种非常常见的访问模式,但是如果不了解您的应用程序,很难保证这会很容易实现。

    一旦您拥有activeOrders维护的字段,您可以在其上构建索引并只需使用简单的查询:

    const shopsWithNoOrders = await mongo.getCollection('shops').find({ activeOrders: 0 });

    关于mongodb - Mongo : Find documents that have 0 associated documents, 更便宜,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/74176951/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com