mongodb学说-具有嵌入式文档复制的批处理插入

时间:2018-08-06 09:08:23

标签: mongodb doctrine-odm

我有一组计算机主机,每个主机都有一个嵌入的文档,其中包含网络数据,即ip地址和cidr网络。

填充集合时,我发现多个网络是重复的,它们也具有相同的ObjectId:

"_id" : ObjectId(""5b683363b873ea53ed3b55f0""),
        "fqdn" : "server.mydomain.com",
        "internalid" : 116852,
        "network_data" : [
                {
                        "_id" : ObjectId(""5b683363b873ea53ed3b55f1""),
                        "address" : "192.168.37.30",
                        "network" : "192.168.37.0/24"
                },
                {
                        "_id" : ObjectId(""5b683363b873ea53ed3b55f1""),
                        "address" : "192.168.37.30",
                        "network" : "192.168.37.0/24"
                }
        ]

这怎么可能?我很确定服务器端插入正确执行。我正在使用MongoDb v3.4.9和Doctrine Mongodb-odm v1.2。

[EDIT]要添加一些信息,这是在插入操作期间收集的日志:

2018-08-06T13:39:15.806+0200 D COMMAND  [conn2] run command adamongo.$cmd { update: "RawNodeData", ordered: true, updates: [ { q: { _id: ObjectId('5b683363b873ea53ed3b55f0') }, u: { $push: { ipAddresses: { $each: [ { _id: ObjectId('5b683363b873ea53ed3b55f1'), address: "192.168.37.30", network: "192.168.37.0/24" } ] } } }, upsert: false, multi: false } ], writeConcern: { w: 1 } }
2018-08-06T13:39:15.806+0200 I WRITE    [conn2] update adamongo.RawNodeData query: { _id: ObjectId('5b683363b873ea53ed3b55f0') } planSummary: IDHACK update: { $push: { ipAddresses: { $each: [ { _id: ObjectId('5b683363b873ea53ed3b55f1'), address: "192.168.37.30", network: "192.168.37.0/24" } ] } } } keysExamined:1 docsExamined:1 nMatched:1 nModified:1 numYields:0 locks:{ Global: { acquireCount: { r: 1, w: 1 } }, Database: { acquireCount: { w: 1 } }, Collection: { acquireCount: { w: 1 } } } 0ms
2018-08-06T13:39:15.806+0200 I COMMAND  [conn2] command adamongo.$cmd command: update { update: "RawNodeData", ordered: true, updates: [ { q: { _id: ObjectId('5b683363b873ea53ed3b55f0') }, u: { $push: { ipAddresses: { $each: [ { _id: ObjectId('5b683363b873ea53ed3b55f1'), address: "192.168.37.30", network: "192.168.37.0/24" } ] } } }, upsert: false, multi: false } ], writeConcern: { w: 1 } } numYields:0 reslen:59 locks:{ Global: { acquireCount: { r: 1, w: 1 } }, Database: { acquireCount: { w: 1 } }, Collection: { acquireCount: { w: 1 } } } protocol:op_query 0ms

似乎有两个具有相同ID和数据的更新操作。

[已解决]经过几次试验,我找到了一种有效的方法来处理可能存在重复项的文档批处理:

    // multiple persist
    $dm->persist($document);

    // batch insertion
    try {

        // commit
        $dm->flush(null, ['continueOnError' => true,  'ordered' => false]);

    } catch (Exception $e) {

        $logger->warning("some duplicates found");

    } finally {

        // clear
        $dm->clear();

    }

如果批处理中存在重复项,则 flush 方法会继续插入其他文档,然后引发异常。

需要 finally 子句,因为必须始终执行 clear 方法,以避免重复插入同一文档。

在这里,主机具有唯一索引,而嵌入式网络则没有。因此,在我的情况下,跳过 clear 操作是网络数据重复插入的原因。

0 个答案:

没有答案