获取一个类型为mongoose的所有文档,但只包含每个文档数组的1个特定项目

时间:2014-11-27 13:05:23

标签: node.js mongodb express mongoose

我正在使用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);
    }
});

1 个答案:

答案 0 :(得分:0)

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