使用gmongo的重复项也不例外

时间:2013-08-08 21:59:12

标签: java mongodb exception groovy duplicates

我尝试使用Groovy和Java将重复项插入到mongodb数据库中。 Java引发异常,而groovy版本只是静静地忽略了插入副本。

以下是一些说明这一点的示例代码。我正在运行OsX,Mongodb版本2.4.4。任何人都可以启发我吗?非常感谢!

package chapter3

import com.gmongo.GMongo
import com.mongodb.BasicDBObject
import com.mongodb.DB
import com.mongodb.DBCollection
import com.mongodb.MongoClient

class TweetArchiveWithJava {
    static void main(String[] args) {
        new TweetArchiveWithJava()
    }

    private static final int ASCENDING = 1

    TweetArchiveWithJava() {
        duplicateInsertGroovy()
        duplicateInsertJava()
    }

    def duplicateInsertJava() {
        println "Inserting duplicates with Java"
        MongoClient mongoClient = new MongoClient()
        DB db = mongoClient.getDB("twitter-archive")
        DBCollection tweets = db.getCollection("tweets")

        tweets.remove(new BasicDBObject())
        tweets.ensureIndex(new BasicDBObject("last_name", ASCENDING), "unique_index", true)

        BasicDBObject insertedRecord = new BasicDBObject("last_name", "jones")
        BasicDBObject duplicate = new BasicDBObject("last_name", "jones")
        tweets.insert(insertedRecord)
        System.out.println("Inserted first one")
        printAllTweets(tweets)
        tweets.insert(duplicate)
        System.out.println("What?!! Should not be able to insert duplicates.")

        printAllTweets(db)
    }

    private void duplicateInsertGroovy() {
        println "Inserting duplicates with Groovy"
        def mongo = new GMongo("127.0.0.1", 27017)
        def db = mongo.getDB("twitter-archive")
        DBCollection tweets = db.getCollection("tweets")

        tweets.remove([:])
        tweets.ensureIndex(new BasicDBObject("last_name", ASCENDING), "unique_index", true)

        def jones = [last_name: "jones"]
        tweets.insert(jones)
        println "Inserted first Jones"
        def duplicate = [last_name: "jones"]
        tweets.insert(duplicate)
        println "Succeeded inserting duplicate"

        println "But only one record is found"
        printAllTweets(tweets)
        println "\n"
    }

    def printAllTweets(tweets) {
        def cursor = tweets.find()
        cursor.each { println it }
    }
}

3 个答案:

答案 0 :(得分:2)

首先,您可以使用WriteResult进行错误指示:

def jones = [last_name: "jones"]
WriteResult rs =  tweets.insert(jones)
println rs.error
//println "Inserted first Jones"
def duplicate = [last_name: "jones"]
rs = tweets.insert(duplicate)
//println "Succeeded inserting duplicate"
println rs.error

打印:

null
E11000 duplicate key error index: twitter.tweets.$unique_index  dup key: { : "jones" }

差异的原因是WriteConcern

java方法代码使用{w=1}(已确认)

而groovy方法代码使用{w=0}(正常)

表格DBTCPConnector

        if ( concern.callGetLastError() ){
            return _checkWriteError( db , port , concern );
        }
        else {
            return new WriteResult( db , port , concern );
        }

WriteConcern

 public boolean callGetLastError(){
    if (_w instanceof Integer)
        return (Integer) _w  > 0;
    return _w != null;
 }

因此java方法在幕后调用_checkWriteError - 抛出异常 - 而groovy方法只返回写入结果。

您有不同的写入问题的原因是初始化代码:

您在java方法中初始化MongoClient mongoClient = new MongoClient(),该方法在内部使用WriteConcern.ACKNOWLEDGED

在你的groovy方法中,GMongo构造函数使用Mongo不推荐使用的构造函数,它在内部使用WriteConcern.NORMAL

如果您将tweets.insert(duplicate)更改为tweets.insert(duplicate, WriteConcern.ACKNOWLEDGED),您也会获得groovy方法的例外

答案 1 :(得分:0)

不确定,但如果将groovy版本更改为:

会发生什么
    def jones = [last_name: "jones"] as BasicDBObject
    tweets.insert(jones)
    println "Inserted first Jones"
    def duplicate = [last_name: "jones"] as BasicDBObject
    tweets.insert(duplicate)

答案 2 :(得分:0)

您也可以使用com.gmongo.GMongoClient。它与com.mongodb.MongoClient具有相同的构造函数。