MongoDB查询过滤器正在执行更新

时间:2017-01-27 15:44:54

标签: mongodb

已编辑。更多说明:

我通过Java异步驱动程序使用MongoDB 3.4 这是我的收藏索引之一:

(?: Non-capturing group. Groups multiple tokens together without creating a capture group.
. Dot. Matches any character except line breaks.
* Star. Match 0 or more of the preceding token.
)
(?: Non-capturing group. Groups multiple tokens together without creating a capture group.
\b Word boundary. Matches a word boundary position such as whitespace, punctuation, or the start/end of the string.
l Character. Matches a "l" character (char code 108).
o Character. Matches a "o" character (char code 111).
c Character. Matches a "c" character (char code 99).
a Character. Matches a "a" character (char code 97).
l Character. Matches a "l" character (char code 108).
h Character. Matches a "h" character (char code 104).
o Character. Matches a "o" character (char code 111).
s Character. Matches a "s" character (char code 115).
t Character. Matches a "t" character (char code 116).
\/ Escaped character. Matches a "/" character (char code 47).
| Alternation. Acts like a boolean OR. Matches the expression before or after the |.
l Character. Matches a "l" character (char code 108).
o Character. Matches a "o" character (char code 111).
c Character. Matches a "c" character (char code 99).
a Character. Matches a "a" character (char code 97).
l Character. Matches a "l" character (char code 108).
h Character. Matches a "h" character (char code 104).
o Character. Matches a "o" character (char code 111).
s Character. Matches a "s" character (char code 115).
t Character. Matches a "t" character (char code 116).
: Character. Matches a ":" character (char code 58).
4 Character. Matches a "4" character (char code 52).
0 Character. Matches a "0" character (char code 48).
8 Character. Matches a "8" character (char code 56).
0 Character. Matches a "0" character (char code 48).
\/ Escaped character. Matches a "/" character (char code 47).
)
( Capturing group #1. Groups multiple tokens together and creates a capture group for extracting a substring or using a backreference.
. Dot. Matches any character except line breaks.
* Star. Match 0 or more of the preceding token.
)

有几天我遇到了异常问题,那就是我在我的数据库中遇到了这样的记录:

posts:{orders.postReqID:1, unique:1}

我不知道原因,我多次删除了这样的子文档。 然后我放了一个带posts: { ..., orders [ ..., { // Please notice there is an implicit postReqID:null viewCount: -1, amount: 1 } ] }, ... 的文档来诊断问题(因为我有一个唯一的索引,它不允许为这个字段添加更多的空值):

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) 子文档中插入任何新的子数组元素,但确实如此。是什么导致这样的?如果您查看第一个文档(在此问题的开头),您会看到ordersviewCount中有两个增量,应该完成,但插入是在{{1}中完成的此查询不是您所看到的。似乎MongoDB没有更新我想要的子数组元素,并在那里放置新元素。

2 个答案:

答案 0 :(得分:2)

$positional运算符的使用存在冲突。

您有两个数组索引在播放visitsorders。根据{{​​1}}的评估顺序,它会将其解析为一个索引值。

在您的情况下,位置运算符正在根据您提供的条件解析为$and的索引值。

现在更新将使用可能没有匹配visits.userID的索引,并使用您提供的查询字段和更新字段为orders创建新条目。

答案 1 :(得分:0)

看起来您已经拥有一个具有空字段值的用户。您只需找到并删除空文档即可。如果文档没有唯一索引中索引字段的值,则通常会出现此问题,索引将为此文档存储空值。

如果您修复了错误,并且想要使用具有空值的多个文档,则可以使用稀疏索引。这是关于稀疏的解释:

https://docs.mongodb.com/manual/core/index-sparse/