我尝试使用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 }
}
}
答案 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具有相同的构造函数。