如何检查MongoDB以查看集合中是否已存在项目

时间:2018-10-15 00:51:39

标签: node.js mongodb mongoose mongoose-schema

我已将项目作为对象数组放入数据库的集合中。现在,我注意到每次服务器重新启动时都会添加项目,从而导致6种产品而不是3种产品。我将如何检查数据库,以查看集合中是否已存在某项,因此不会重复该项?目前,我收到“ ReferenceError:标题未定义”

Product.js(模型)

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const ProductSchema = new Schema({
    product_id: {
        type: String,
        // required: true
    },
    imagepath: {
        type: String
        // required: true
    },
    title: {
        type: String
        // required: true
    },    
    description: {
        type: String
        // required: true
    },
    price: {
        type: Number
        // required: true
    },
});

Product-seeder.js(填充产品集合)

module.exports = Product = mongoose.model('products', ProductSchema);
const Product = require('../models/Product');
const mongoose = require('mongoose');

const products = [
    new Product ({
        imagePath: '../client/src/Components/Layout/Media/armadillo.png',
        title: 'Pangolin',
        description: "This is a pangolin",
        price: 15000
    }),
    new Product ({
        imagePath: '../client/src/Components/Layout/Media/croc.png',
        title: 'Cuban corcodile',
        description: "This is a croc",
        price: 15000
    }),
    new Product ({
        imagePath: '../client/src/Components/Layout/Media/monkey.png',
        title: 'Golden Gibbon',
        description: "This is a monkey",
        price: 15000
    })
];

for (let i = 0; i < products.length; i++) {
    Product.findOne({title: title})
    .then(products => {
        if (!product) {
        products[i].save();
        } 
    }); 
}
mongoose.disconnect();

2 个答案:

答案 0 :(得分:0)

您在查询中犯了两个错误。

  

使用@DBusInterfaceName("com.victronenergy.BusItem")代替products[i].title

     

使用title或任何其他变量更改产品。

results

答案 1 :(得分:0)

还有另一种方法可以解决此问题;使用原始对象数组代替带有 bulkWrite 的Mongoose文档。

bulkWrite 允许您发送多个insertOneupdateOneupdateManyreplaceOnedeleteOne,和/或deleteMany操作通过一个命令对MongoDB服务器进行操作,而不是通过for循环向服务器发送多个命令的当前设置。在这种情况下,您需要执行多个 updateOne 操作,而更新操作为 $setOnInsert

例如,假设您有一个数组

const products = [
    {
        imagePath: '../client/src/Components/Layout/Media/armadillo.png',
        title: 'Pangolin',
        description: "This is a pangolin",
        price: 15000
    },
    {
        imagePath: '../client/src/Components/Layout/Media/croc.png',
        title: 'Cuban corcodile',
        description: "This is a croc",
        price: 15000
    },
    {
        imagePath: '../client/src/Components/Layout/Media/monkey.png',
        title: 'Golden Gibbon',
        description: "This is a monkey",
        price: 15000
    }
];

您可以设置 updateOne 操作列表,该列表可以采用以下格式

[
   { updateOne :
      {
         "filter" : <document>,
         "update" : <document>,
         "upsert" : <boolean>
      }
   }
]

将商品数组映射为上面的

const ops = products.map(product => (
    { "updateOne": {
        "filter": { "title": product.title },
        "update": { "$setOnInsert": product },
        "upsert": true
    } }
))

然后您可以按以下方式在上面应用 bulkWrite()

Product.bulkWrite(ops).then(result => console.log(result))

在上面,如果存在匹配的文档,则使用 $setOnInsert 进行的更新不会执行任何操作,因为更新操作不会导致插入,而找到了与查询匹配的文档。


如果要使用原始实现,则需要修复查询,然后在for循环中按以下方式构建Promise:

let promises = [];
for (let i = 0; i < products.length; i++) {
    const productPromise = Product.findOne({
        title: products[i].title // <- fixed
    }).then(product => {
        if (!product) { // <-- fixed
            return products[i].save();
        } 
    });
    promises.push(productPromise);
}

Promise.all(promises).then(result => console.log(result));