素材牛VIP会员
MongoDB3.2中插入数据前如何去重
 13***62  分类:Node.js  人气:1714  回帖:4  发布于6年前 收藏

场景描述:

现有类似 {key:"value",key1:"value1"} 这样的文档。
我使用db.collection.insertMany()将文档批量插入到集合之中,例如:

db.collection.insertMany([
   {key:"1",key1:"value1"},
   {key:"2",key1:"value1"},
   {key:"3",key1:"value1"},
            ……
]);

具体问题描述:

我需要key的值是唯一的,在批量插入的时候自动舍弃掉有重复值的文档。
我有尝试使用db.collection.createIndex({key:1},{unique:true})给这个集合添加 unique 索引,但结果是插入时如果遇到重复值,直接会中断插入并且抛出错误。

问题:

请问在数据库层面有没有解决此问题的办法?
【修改:】请问在数据库层面不将唯一值赋给“_id”有没有解决此问题的办法?
难道只有在语言层面做判断?

附:
db.collection.insertMany文档
unique index 文档

 标签:mongodbnode.jsphp

讨论这个帖子(4)垃圾回帖将一律封号处理……

Lv1 新人
10***19 学生 6年前#1

将key的值给_id

Lv2 入门
馨***茂 站长 6年前#2

你看下你自己附带的文档,里面专门有提到的:

With ordered to false, the insert operation would continue with any remaining documents.

Unordered Inserts

The following attempts to insert multiple documents with _id field and ordered: false. The array of documents contains two documents with duplicate _id fields.

try {
db.products.insertMany( [

  { _id: 10, item: "large box", qty: 20 },
  { _id: 11, item: "small box", qty: 55 },
  { _id: 11, item: "medium box", qty: 30 },
  { _id: 12, item: "envelope", qty: 100},
  { _id: 13, item: "stamps", qty: 125 },
  { _id: 13, item: "tape", qty: 20},
  { _id: 14, item: "bubble wrap", qty: 30}

], { ordered: false } );
} catch (e) {
print (e);
}

Lv6 码匠
bo***18 产品经理 6年前#3

找到目前比较好的办法:

  1. 设置 keyunique index。

  2. 当使用db.collection.insertMany()插入多文档时,使用ordered: false 选项跳过插入错误的文档,不中断插入操作。

  3. 最后对插入重复值抛出的异常做处理。

例如:

此处用 PHP 作为示例。


try {
    //首先对 key 字段添加唯一索引
    $this->collection->createIndex(['key' => 1], ["unique" => true]);
} catch (\MongoDB\Driver\Exception\Exception $e) {
    Log::error($e->getMessage());
}

try {
    $result = $this->collection->insertMany(
        $data,
        ['ordered' => false] //跳过插入错误
    );
} catch (\MongoDB\Driver\Exception\BulkWriteException $e) {
    /*如果有重复数据插入,将抛出 BulkWriteException */
    $result       = $e->getWriteResult(); 
    $writeErrors  = $result->getWriteErrors(); 
    $errorsAmount = count($writeErrors); //插入错误的数量
    Log::info($errorsAmount . '条重复数据未插入!');
} catch (\MongoDB\Driver\Exception\Exception $e) {
    Log::error($e->getMessage());
    exit;
}
Lv1 新人
阿***扫 JAVA开发工程师 6年前#4

nodejs开发,使用mongoose连接mongodb。
在数据库层面达到,批量插入数据,去重问题。
1.设置key为unique indx

let urlSchema = new Schema({
    url: String,
    status: Number,
  },
);
urlSchema.index({ url: 1 }, { unique: true, background: true, dropDups: true })
  1. insertMany插入多条文档,使用{ordered:false}跳过插入错误的文档,避免插入中断

 let UrlModel = mongoose.model('url', urlSchema);
    UrlModel.insertMany([{url:'123', status:0}, {url:'123', status:0}, {url:'1234', status:0}], { ordered: false })
    .then()
    .catch(err => { //捕捉插入重复抛出的异常
        console.log(err.toString())
    });

Note: ordered operations stop after an error, while unordered(ordered:false) operations continue to process any remaining write operations in the queue.

https://docs.mongodb.com/manu...

 文明上网,理性发言!   😉 阿里云幸运券,戳我领取