【问题标题】:Get all documents of a type in mongoose but only with 1 specific item of each documents array获取猫鼬类型的所有文档,但每个文档数组只有一个特定项目
【发布时间】:2015-01-26 02:21:04
【问题描述】:

我将 Express 4 和 Mongoose 用于我的 REST API。所以我有多个“商店”类型的文件。每个商店都持有(除其他信息外)一个称为“库存”的数组,该数组再次保存多个商品。每个项目本身都有名称和价格等属性。

现在我想要一个 API 调用,我可以在其中获取所有商店,但只能在 json 响应中使用他们的“最便宜”产品项目。但是我完全坚持创建这个返回我所有商店的查询,而不是包括库存的所有项目,只包括价格最低的库存项目作为库存数组中的唯一项目。

我发现了一些关于如何使用以下查询排除字段的提示,但整个数组将被排除:

Shop.find({},  {inventory: 0},function(err, shops) {
    if (err) {
        res.send(err);
    } else {
        res.json(shops);
    }
});

更新 1:我的架构

// Shop
var ShopSchema = new Schema({
    name: { type: String, required: true},
    address: {
        street: String,
        zipCode: Number,
        city: String
    },
    inventory: [InventoryItemSchema]
});

// InventoryItem
var InventoryItemSchema = new Schema({
    name: { type: String, required: true},
    currentPrice: {
        amount: { type: Number, required: true },
        added: Date
    },
    pastPrices: []
});

更新 2:这就是我想出的

Shop.find(function(err, shops) {
    if (err) {
        res.send(err);
    } else {

        shops.forEach(function(shop) {
            // Only keep the currently cheapest inventory Item in the array
            var cheapestInventoryItem;
            shop.inventory.reduce(function (previousItem, currentItem) {
                if (currentItem.currentPrice.amount < previousItem.currentPrice.amount) {
                    cheapestInventoryItem = currentItem;
                    return currentItem;
                } else {
                    cheapestInventoryItem = previousItem;
                    return previousItem;
                }
            });
            shop.inventory = [cheapestInventoryItem];
        });

        res.json(shops);
    }
});

【问题讨论】:

    标签: node.js mongodb express mongoose


    【解决方案1】:

    Mongodb find 方法返回一个文档。因此,在您的情况下,无论如何,这将是一系列带有折叠字段的商店。

    你可以用js过滤项目:

    var cheapestItem;
    var cheapestPrice = shop.inventory.items.reduce(function (lowest, item) {
        if (item.price < lowest) {
            cheapestItem = item;
            return item.price;
        }
    }, Infinity);
    

    或者您可以规范化您的架构并创建集合项目:

    [{itemId: 1, shopId: 1, price: 100}]
    

    所以查询是:

    db.Item.group(
    {
         key: { shopId: 1, itemId: 1, price: 1 },
         reduce: function ( lowest, res ) { if (result.price < lowest) return result.price },
         initial: Infinity
    })
    

    所以你必须以最低的价格获得shopId和itemId

    【讨论】:

    • 对不起,我还是没听懂……我刚刚用我的 Schemas 更新了我的原始帖子。 “规范化您的架构”是什么意思?
    • 很好,我的意思是一样的。您应该只将 shopId 添加到 InventoryItem 并使用 mongo 分组。如果它适合您的业务逻辑
    • 我想我太菜鸟了,才能以正确的方式做到这一点。但是,感谢您对 reduce 功能的提示,我设法得到了我想要的东西(请参阅我的原始帖子)。绝对不是最好的方法,但它确实有效。非常感谢!
    猜你喜欢
    • 2022-12-23
    • 1970-01-01
    • 1970-01-01
    • 2021-05-11
    • 2019-10-06
    • 2013-10-21
    • 2017-01-28
    • 2015-10-23
    • 1970-01-01
    相关资源
    最近更新 更多