Как проверить MongoDB, чтобы увидеть, существует ли элемент в коллекции - PullRequest
0 голосов
/ 15 октября 2018

Я поместил свои предметы в коллекцию в моей базе данных как массив объектов.Теперь я заметил, что элементы добавляются каждый раз при перезапуске сервера, в результате чего получается 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 голосов
/ 15 октября 2018

Есть еще один способ сделать это;используйте исходный массив объектов вместо документов Mongoose с bulkWrite.

bulkWrite позволяет отправлять несколько insertOne, updateOne, updateMany, replaceOne, deleteOne и / или deleteMany операций на сервере MongoDB в одной команде вместо текущей настройки, когда вы отправляете несколько команд на сервер с циклом for.В этом случае вам потребуется несколько updateOne операций с операцией обновления как $setOnInsert.

Takeнапример, предположим, что у вас есть массив

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 следующим образом:

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));
0 голосов
/ 15 октября 2018

Вы допустили две ошибки в своем запросе.

Используйте products[i].title вместо title.

Замените продукты с помощью results или любой другой переменной.

for (let i = 0; i < products.length; i++) {
    console.log(products[i]);
    Product.findOne({title: products[i].title}) //products[i].title 
    .then(results => { //update products with results
      console.log(results)
        if (!results) {
        products[i].save();
        } 
    }); 
}
});
...