为什么writeresult只返回acknowledged=false

MongoDB: WriteResult.getN() always returns 0? - Stack Overflow
Join the Stack Overflow Community
Stack Overflow is a community of 6.8 million programmers, just like you, helping each other.
J it only takes a minute:
According to the , getN() method of WriteResult class in MongoDB-java returns the number of documents updated in the opertion.
But it always returns zero, even if the document is inserted correctly.
Why so? or I understood it wrongly?
1,34731934
I was under the impression that this was the normal MongoDB behaviour, and has nothing to do with the Java driver.
The only thing I can find in the documentation is :
getLastError.n reports the number of documents updated or removed, if the preceding operation was an update or remove operation.
An insert being neither an update nor a remove, n doesn't seem to be specified and 0 is as good a default value as any. You can check it easily enough in the mongo shell:
& db.test.insert({_id: 'test'})
& db.getLastErrorObj()
{ "n" : 0, "connectionId" : 7, "err" : null, "ok" : 1 }
Unless I'm mistaken, it's not really an issue: ask yourself under which circumstances the insert would fail (other than, say, a connection failure). The only one I can think of is a unicity constraint violation, which would result in an exception. So almost by definition, the fact that you receive a WriteResult instance at all means the operation was successful and a document was inserted.
A couple of notes:
my previous argument hinges on your WriteConcern being high enough that errors are reported. If you're using WriteConcern.NONE, for example, no exception will ever be raised.
if the number of updated documents is an absolute must for you, you can always use save instead of insert. Not very clean, but it behaves the way you seem to expect.
Note that regardless of what the
states, the
method always returns 0 for insert using the Java driver, regardless of the number of objects inserted. The source code for setting the "n" field in the 2.12.3 of the Java driver:
if (type == INSERT) {
commandResult.put("n", 0);
} else if (type == REMOVE) {
commandResult.put("n", bulkWriteResult.getRemovedCount());
} else if (type == UPDATE || type == REPLACE) {
commandResult.put("n", bulkWriteResult.getMatchedCount() + bulkWriteResult.getUpserts().size());
if (bulkWriteResult.getMatchedCount() & 0) {
commandResult.put("updatedExisting", true);
commandResult.put("updatedExisting", false);
if (!bulkWriteResult.getUpserts().isEmpty()) {
commandResult.put("upserted", bulkWriteResult.getUpserts().get(0).getId());
But errors are correctly reported via Exceptions. For example, a MongoException will be thrown when inserting a document that violates a unique index, if WriteConcern specified is at least the ACKNOWLEDGED
You may also want to check
The dafault behaviour is not to use the "safe" write concern
1,10811326
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Not the answer you're looking for?
Browse other questions tagged
The week's top questions and answers
Important community announcements
Questions that need answers
By subscribing, you agree to the
rev .25306
Stack Overflow works best with JavaScript enabledjava - MongoDB ACKNOWLEDGED write concern faster than UNACKNOWLEDGED? - Stack Overflow
Join the Stack Overflow Community
Stack Overflow is a community of 6.8 million programmers, just like you, helping each other.
J it only takes a minute:
I've got a very simple test program that performs faster with ACKNOWLEDGED bulk inserts than with UNACKNOWLEDGED. And it's not just a little faster - I'm seeing a factor of nearly 100!
My understanding of the difference between these two write concerns is solely that with ACKNOWLEDGED the client waits for confirmation from the server that the operation has been executed (but not necessarily made durable), while with UNACKNOWLEDGED the client only knows that the request made it out onto the wire. So it would seem preposterous that the former could actually perform at a higher speed, yet that's what I'm seeing.
I'm using the Java driver (v2.12.0) with Oracle's Java JDK v1.7.0_71, and mongo version 3.0.0 on 64-bit Windows 7. I'm running mongod, completely out-of-the-box (fresh install), no sharding or anything. And before each test I ensure that the collection is empty and has no non-default indexes.
I would appreciate any insight into why I'm consistently seeing the opposite of what I'd expect.
Here's my code:
import com.mongodb.BasicDBO
import com.mongodb.BulkWriteO
import com.mongodb.BulkWriteR
import com.mongodb.DBC
import com.mongodb.DBO
import com.mongodb.MongoC
import com.mongodb.ServerA
import com.mongodb.WriteC
import java.util.A
public class Test {
private static final int BATCHES = 100;
private static final int BATCH_SIZE = 1000;
private static final int COUNT = BATCHES * BATCH_SIZE;
public static void main(String[] argv) throws Exception {
DBCollection coll = new MongoClient(new ServerAddress()).getDB("test").getCollection("test");
for (String wcName : Arrays.asList("UNACKNOWLEDGED", "ACKNOWLEDGED")) {
WriteConcern wc = (WriteConcern) WriteConcern.class.getField(wcName).get(null);
coll.dropIndexes();
coll.remove(new BasicDBObject());
long start = System.currentTimeMillis();
BulkWriteOperation bulkOp = coll.initializeUnorderedBulkOperation();
for (int i = 1; i & COUNT; i++) {
DBObject doc = new BasicDBObject().append("int", i).append("string", Integer.toString(i));
bulkOp.insert(doc);
if (i % BATCH_SIZE == 0) {
BulkWriteResult results = bulkOp.execute(wc);
if (wc == WriteConcern.ACKNOWLEDGED && results.getInsertedCount() != 1000) {
throw new RuntimeException("Bogus insert count: " + results.getInsertedCount());
bulkOp = coll.initializeUnorderedBulkOperation();
long time = System.currentTimeMillis() -
double rate = COUNT / (time / 1000.0);
System.out.printf("%s[w=%s,j=%s]: Inserted %d documents in %s @ %f/sec\n",
wcName, wc.getW(), wc.getJ(), COUNT, duration(time), rate);
private static String duration(long msec) {
return String.format("%d:%02d:%02d.%03d",
msec / (60 * 60 * 1000),
(msec % (60 * 60 * 1000)) / (60 * 1000),
(msec % (60 * 1000)) / 1000,
msec % 1000);
And here's typical output:
UNACKNOWLEDGED[w=0,j=false]: Inserted 100000 documents in 0:01:27.025 @ /sec
ACKNOWLEDGED[w=1,j=false]: Inserted 100000 documents in 0:00:00.927 @ 156/sec
Ran more extensive tests, per request from Markus W. Mahlberg. For these tests, I ran the code with four write concerns: UNACKNOWLEDGED, ACKNOWLEDGED, JOURNALED, and FSYNCED. (I would expect this order to show decreasing speed.) I ran 112 repetitions, each of which performed 100 batches of 1000 inserts under each of the four write concerns, each time into an empty collection with no indexes. Code was identical to original post but with two additional write concerns, and with output to CSV format for easy analysis.
Results summary:
UNACKNOWLEDGED:
docs/sec avg, std dev 27.
ACKNOWLEDGED:
docs/sec avg, std dev
JOURNALED:
docs/sec avg, std dev 123.9927554
docs/sec avg, std dev 147.6150994
The huge inverted performance difference between UNACKNOWLEDGED and ACKNOWLEDGED is what's got me baffled.
Here's the raw data if anyone cares for it ("time" is elapsed msec for 100*1000 "rate" is docs/second):
"UNACK time","UNACK rate","ACK time","ACK rate","JRNL time","JRNL rate","FSYNC time","FSYNC rate"
.9,.85,3,474726
.8,.84,1,588586
.5,.80,4,167848
.3,.82,,345577
.,.78,,568722
.,.75,,588586
.6,.76,0,568047
Know someone who can answer? Share a link to this
via , , , or .
Your Answer
Sign up or
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Post as a guest
By posting your answer, you agree to the
Browse other questions tagged
rev .25306
Stack Overflow works best with JavaScript enabled

我要回帖

 

随机推荐