EDITEDより明確化:MongoDBクエリフィルタが更新として実行されています
私はJavaの非同期ドライバを介してのMongoDB 3.4を使用
これは私のコレクションの指標の一つである:日間
posts:{orders.postReqID:1, unique:1}
私は異常な問題を抱えていたし、それは私がこのような記録に直面しました私のデータベース:
posts:
{
...,
orders
[
...,
{
// Please notice there is an implicit postReqID:null
viewCount: -1,
amount: 1
}
]
}, ...
私は原因を知らなかったので、このようなサブ文書を何度も削除しました。 は、それから私は(私はこの分野のためのより多くのNULL値を入れることはできないだろう、一意のインデックスを持っていたので)問題を診断するorders.postReqID:null
で文書を置く:
{ //This is the document I inserted inside my db
...
orders:
[
{
postReqID:Null
date:0
viewCount:0
remaining:0
}
]
}
これは私が容疑者だったクエリです:
posts.findOneAndUpdate(
and(new Document("visits.userID", userID),
new Document("orders.postReqID", postReqID)
),
new Document("$inc",
new Document("orders.$.viewCount", 1)
.append("orders.$.remaining", -1)
)
.append("$set", new Document("orders.$.endDate", currentTime)
.append("visits.$.date", currentTime)),
(r, t) ->
{
if (t != null)
{
t.fillInStackTrace();
t.printStackTrace();
}
}
)
そして、私は(私のデシベルの内側にその文書を入れて、もう一度、このクエリを実行した後に)このようなエラーが発生します。
com.mongodb.MongoCommandException: Command failed with error 11000: 'E11000 duplicate key error collection: ViewMember.posts index: orders.postReqID_1 dup key: { : null }' on server localhost:27017. The full response is { "ok" : 0.0, "errmsg" : "E11000 duplicate key error collection: ViewMember.posts index: orders.postReqID_1 dup key: { : null }", "code" : 11000, "codeName" : "DuplicateKey" }
at com.sunova.bot.MongoDBDriver$14.lambda$requestAsync$1(MongoDBDriver.java:768)
at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
at com.mongodb.async.client.MongoClientImpl$2$2.onResult(MongoClientImpl.java:144)
at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
at com.mongodb.operation.OperationHelper$ReferenceCountedReleasingWrappedCallback.onResult(OperationHelper.java:368)
at com.mongodb.operation.CommandOperationHelper$1.onResult(CommandOperationHelper.java:381)
at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor$1.onResult(DefaultServer.java:185)
at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
at com.mongodb.connection.CommandProtocol$CommandResultCallback.callCallback(CommandProtocol.java:275)
at com.mongodb.connection.ResponseCallback.onResult(ResponseCallback.java:48)
at com.mongodb.connection.ResponseCallback.onResult(ResponseCallback.java:23)
at com.mongodb.connection.DefaultConnectionPool$PooledConnection$2.onResult(DefaultConnectionPool.java:470)
at com.mongodb.connection.DefaultConnectionPool$PooledConnection$2.onResult(DefaultConnectionPool.java:464)
at com.mongodb.connection.UsageTrackingInternalConnection$3.onResult(UsageTrackingInternalConnection.java:119)
at com.mongodb.connection.UsageTrackingInternalConnection$3.onResult(UsageTrackingInternalConnection.java:115)
at com.mongodb.internal.async.ErrorHandlingResultCallback.onResult(ErrorHandlingResultCallback.java:49)
at com.mongodb.connection.InternalStreamConnection.executeCallbackAndReceiveResponse(InternalStreamConnection.java:378)
at com.mongodb.connection.InternalStreamConnection.access$1700(InternalStreamConnection.java:66)
at com.mongodb.connection.InternalStreamConnection$ResponseBuffersCallback.onResult(InternalStreamConnection.java:420)
at com.mongodb.connection.InternalStreamConnection$ResponseBuffersCallback.onResult(InternalStreamConnection.java:389)
at com.mongodb.connection.InternalStreamConnection$ResponseHeaderCallback.onSuccess(InternalStreamConnection.java:562)
at com.mongodb.connection.InternalStreamConnection$ResponseHeaderCallback.access$2200(InternalStreamConnection.java:517)
at com.mongodb.connection.InternalStreamConnection$ResponseHeaderCallback$ResponseBodyCallback.onResult(InternalStreamConnection.java:584)
at com.mongodb.connection.InternalStreamConnection$ResponseHeaderCallback$ResponseBodyCallback.onResult(InternalStreamConnection.java:568)
at com.mongodb.connection.InternalStreamConnection$3.completed(InternalStreamConnection.java:447)
at com.mongodb.connection.InternalStreamConnection$3.completed(InternalStreamConnection.java:444)
at com.mongodb.connection.AsynchronousSocketChannelStream$BasicCompletionHandler.completed(AsynchronousSocketChannelStream.java:218)
at com.mongodb.connection.AsynchronousSocketChannelStream$BasicCompletionHandler.completed(AsynchronousSocketChannelStream.java:201)
at sun.nio.ch.Invoker.invokeUnchecked(Invoker.java:126)
at sun.nio.ch.Invoker$2.run(Invoker.java:218)
at sun.nio.ch.AsynchronousChannelGroupImpl$1.run(AsynchronousChannelGroupImpl.java:112)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)
この例外は、このクエリによって実行されるべきではない、このクエリによって行われた異常な更新が存在することを意味します。このクエリは、新しいサブ配列要素をorders
サブドキュメントに挿入しないでください。これは何の原因になりますか?最初の文書(この質問の冒頭にある)を見ると、viewCount
とamount
に2つのインクリメントが発生していることがわかりますが、このクエリで挿入されるのはorders
です。 MongoDBは私が意図したサブ配列要素を更新せず、新しい要素をそこに置きます。
これは、私の文書の2つの配列フィールド内を1つのクエリで検索できないということですか?他に何ができるのか教えていただけますか?これを解決するためにクエリを変更するにはどうすればよいですか? –
私はポジション演算子を使用しないことを意味します。一度に1つの配列をクエリ部分から見つかった適切なインデックスで更新するだけで済みます。 – Veeram
と思われます。ご回答いただきありがとうございます:)私は私のコードを変更し、それを受け入れたとしてあなたの答えをマークします。 –