"E11000 duplicate key error" when doing replace_one with upsert (c++ driver)

198 views
Skip to first unread message

VioletGiraffe

unread,
Oct 15, 2018, 1:25:44 AM10/15/18
to mongodb-user
I'm using the C++ driver to do bulk `replace_one` operation with "_id" as the only filter. And I'm getting E11000 after some time running the program, always.

Since I'm generating the IDs myself, I thought my keys are simply colliding. But 1) they aren't, I triple check through logging all operations and analyzing the log with a purpose-written tool; and 2) even if they were, `replace_one` with filter on "_id" should simply replace the existing document, right?..
So how is this error even possible??? I'm at a loss.


bool CMongoDbInterface::registerTokens(const std::vector<std::string>& tokens)
{
   
if (tokens.empty())
       
return true;

   
try {
       
auto client = get_client();
       
auto db = client->database("web");
       
auto tokenCollection = db.collection("tokens");
        mongocxx
::bulk_write bulk{};

       
for (auto item = tokens.cbegin(), end = tokens.cend(); item != end; ++item)
       
{
           
const auto nextItem = std::next(item); // <- The source token list is already sorted, so duplicate items shall not pass
           
if (nextItem != end && *item == *nextItem)
               
continue;

           
const auto tokenId = hash128bit(*item);
            logHash
(item->text);// <- I'm watching all the hashes for collisions, there weren't any!
            basic
::document basic_builder{};
            basic_builder
.append(kvp("_id", binaryFromArray(tokenId))); // binaryFromArray constructs bsoncxx::types::b_binary from std::array
            basic_builder
.append(kvp("token", bsonstring(item->text)));

            mongocxx
::model::replace_one upsert_op{ stream::document{} << "_id" << binaryFromArray(tokenId) << stream::finalize, basic_builder.view() };
            upsert_op
.upsert(true);

            bulk
.append(upsert_op);
       
}

       
const auto result = tokenCollection.bulk_write(bulk);
       
return (bool)result; //&& (result->upserted_count() + result->matched_count() == uniqueItems);
   
}
   
catch (mongocxx::bulk_write_exception& e) {
        assert_unconditional_r
(std::string("MongoDB bulk_write exception: ") + e.what());
       
return false;
   
}
}


Asya Kamsky

unread,
Oct 19, 2018, 11:28:55 AM10/19/18
to mongod...@googlegroups.com
See this section in the docs which talks about this:
You can also see discussion about whether the server might be able to handle a subset of these cases automatically:
Asya

--
You received this message because you are subscribed to the Google Groups "mongodb-user"
group.
 
For other MongoDB technical support options, see: https://docs.mongodb.com/manual/support/
---
You received this message because you are subscribed to the Google Groups "mongodb-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email to mongodb-user...@googlegroups.com.
To post to this group, send email to mongod...@googlegroups.com.
Visit this group at https://groups.google.com/group/mongodb-user.
To view this discussion on the web visit https://groups.google.com/d/msgid/mongodb-user/8e376206-a3d8-42f9-8479-bf4074a4586a%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
Asya Kamsky
Principal Product Manager
MongoDB
Download MongoDB - mongodb.org/downloads
We're Hiring! - https://www.mongodb.com/careers
Reply all
Reply to author
Forward
0 new messages