$or 来自 mongoose 的运算符在与 find() 方法一起使用时未提供所有必要的数据

问题描述 投票:0回答:1

我正在使用 find 方法和 $or 运算符来检查数据库中是否存在此行中任何现有的重复数据

const duplicate = await NewItemsData.find({ $or: newItems });
检查控制台中的变量
console.log(duplicate)
我发现获取的一些数据丢失了。这是代码:

请帮我知道这个问题是从哪里来的。代码的目的是创建一个包含重复数据的数组,然后过滤 newItems 数组,创建另一个包含 newItems 数组中存在但不存在重复数组中的数据的数组。

const createMoneyInTransact = asyncHandler(async (req, res) => {
 const {newItems}= req.body
 console.log(newItems)

//check the database to see if any data found in the newItems array coming in from the frontend
//already exists in the NewItemsData database if it exists, create a new array of all duplicates

  const duplicate = await NewItemsData.find({ $or: newItems });
  console.log(duplicate)
     if(Array.isArray(duplicate) && duplicate.length === 0){
        console.log('no duplicates')
         const create_newItems = await NewItemsData.create(newItems)
       console.log(create_newItems)
    }else{
        console.log('duplicate exists')
        //helper function that compares two objects in arrays by their properties
    const containsObject=(obj, arr, key)=>{
        return arr.some((element)=>{
            return element[key] === obj[key]
        })

     }

     // Filter the newItems array and keep only the objects that are 
     //not in the duplicate array
     const newUniqueItems = newItems.filter((obj)=>{
         return !containsObject(obj, duplicate, 'productName')
     })

     console.log(newUniqueItems)
     const create_newUniqueItems = await NewItemsData.create(newUniqueItems)
     console.log(create_newUniqueItems)

    }
})


//console.log Data
//console.log(newItems) displays the result below
[
  {
    productName: 'vally',
    sellingPriceOfTotal: 3619,
    quantityCount: 11,
    unitOfQuantity: 'grams',
    sellingPrice: '329'
  },
  {
    productName: 'Tridant',
    sellingPriceOfTotal: 2400,
    quantityCount: 4,
    unitOfQuantity: 'grams',
    sellingPrice: '600'
  },
  {
    productName: 'trulia',
    sellingPriceOfTotal: 1600,
    quantityCount: 4,
    unitOfQuantity: 'kg',
    sellingPrice: '400'
  },
  {
    productName: 'constr',
    sellingPriceOfTotal: 1362,
    quantityCount: 3,
    unitOfQuantity: 'kg',
    sellingPrice: '454'
  }
]
//console.log(duplicate) displays the result below
[
  {
    _id: new ObjectId("6598d46d37efd2db72ee9ecd"),
    productName: 'Tridant',
    sellingPriceOfTotal: '2400',
    quantityCount: 4,
    unitOfQuantity: 'grams',
    sellingPrice: 600,
    __v: 0
  },
  {
    _id: new ObjectId("6599150ebd9fedd3f0b9e721"),
    productName: 'trulia',
    sellingPriceOfTotal: '1600',
    quantityCount: 4,
    unitOfQuantity: 'kg',
    sellingPrice: 400,
    __v: 0
  }
]

//productName: vally was surposed to be among the duplicate but was not picked up
//console.log(newUniqueItems) displays the result below
[
  {
    productName: 'vally',
    sellingPriceOfTotal: '3619',
    quantityCount: 11,
    unitOfQuantity: 'grams',
    sellingPrice: 329
  },
  {
    productName: 'constr',
    sellingPriceOfTotal: '1362',
    quantityCount: 3,
    unitOfQuantity: 'kg',
    sellingPrice: 454
  }
]
//but vally is not supposed to be among the filtered array because it is a duplicate hence
//the errow message below

MongoServerError: E11000 duplicate key error collection: test.newitemsdatas index: productName_1 dup key: { productName: "vally" }
    at C:\Users\USER\Desktop\bussiness-books\server\node_modules\mongodb\lib\operations\insert.js:50:33
    at C:\Users\USER\Desktop\bussiness-books\server\node_modules\mongodb\lib\operations\command.js:84:64
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)

//here is the NewItemsData Data Model
const mongoose = require('mongoose');
const MoneyInData = require('./MoneyInData');

const newItemsSchema = new mongoose.Schema({

    productName:{
        type: String,
        required: true,
        unique: true
    },
    sellingPriceOfTotal:{
      type: String,
      //required: true
    },
    quantityCount: {
        type: Number,
    },
    unitOfQuantity:{
        type: String,
    },
    costPrice:{
      type: Number,
      //required: true
    },
    sellingPrice:{
        type: Number,
       required:true
    },
    moneyInData:{
        type: mongoose.Schema.Types.ObjectId,
        ref: 'MoneyInData'
    },

})

module.exports = mongoose.model('NewItemsData', newItemsSchema);

javascript node.js mongodb mongoose
1个回答
0
投票

看起来您只需要检查查询中的

productName
匹配项。在您检查整个文档匹配的那一刻,我的意思是所有五个
[ productName, sellingPriceOfTotal, quantityCount, unitOfQuantity, sellingPrice]
都需要完全匹配才能使对象匹配。我怀疑您收藏中带有
productName: 'vally'
的文档与您用于搜索的文档有细微的差别。

相反,只需尝试其中一项即可在

productName
上查找匹配项。

选项 1 使用

$or

const {newItems} = req.body;

// Create a new array of objects containing just the productName and it's value
const newItemsNamesObj = newItems.map(o =>{
  return {productName: o.productName}
})
//Then search using $or
const duplicate = await NewItemsData.find({ 
   $or: newItemsNamesObj 
});

选项 2 使用

$in

const {newItems} = req.body;

// Create a new array of String containing just the productName
const newItemsNamesStr = newItems.map(o =>{
  return o.productName
})
//Then search
const duplicate = await NewItemsData.find({
   productName: {
      $in: newItemsNamesStr
   }
});
© www.soinside.com 2019 - 2024. All rights reserved.