Mongoose 在更新文档时忽略 $ne

Mongoose ignores $ne while updating document

我正在为后端使用 Node、Mongoose 和 Socket.io 构建持久性 html 字段框架。我已经 运行 发现了 Mongoose 更新方法中的一个错误。

mongo 中的文档如下所示:

{
    "_id" : "pickable_qty",
    "currently_connected" : [ ],
    "locks" : [
        {
            socket_id: 'eQYVyz1z28rJZRPpAAAB',
            unique_values:{
                merchant_warehouse_id: 11.1,
                product_item_id: 5555
            }
        },
        {
            socket_id: 'eQYVyz1z28rJZRPpAAAB',
            unique_values:{
                merchant_warehouse_id: 11.2,
                product_item_id: 5555
            }
        },
        {
            socket_id: 'eQYVyz1z28rJZRPpAAAB',
            unique_values:{
                merchant_warehouse_id: 11.1,
                product_item_id: 1234
            }
        }
    ],
    "definition" : {
        "ajax_url" : "/persistent-fields/pickable_qty",
        "unique_keys" : [
            "product_item_id",
            "merchant_warehouse_id"
        ],
        "max_idle_seconds" : 30,
        "field_type" : "text"
    },
    "__v" : 0
}

当我开始将子文档插入 locks 数组时出现问题。

我使用 Mongoose 的 update 方法插入它们,如下所示:

FieldSchema.update(
    {
        _id: 'pickable_qty',
        'locks.unique_values': { 
            '$ne': { 
                merchant_warehouse_id: 11.1, 
                product_item_id: 5334 
            } 
        },
        'definition.unique_keys': { 
            '$all': [ 
                'merchant_warehouse_id', 
                'product_item_id' 
            ] 
        } 
    },
    {
        '$push': {
            locks: { 
                socket_id: 'eQYVyz1z28rJZRPpAAAB', 
                unique_values: {
                    merchant_warehouse_id: 11.1, 
                    product_item_id: 5334 
                } 
            } 
        }
    },
    function(err, count, res){
        console.log('err:', err, 'count:', count, 'res:', res);
        //err: null count: 1 res: { ok: true, n: 1, updatedExisting: true }
    }
);

第一次插入完全按预期工作,数组中没有 locks 包含唯一值 {merchant_warehouse_id: 11.1,product_item_id: 5334},因此找到了文档并插入了 lock 子文档。

但是 运行第二次进行同样的更新不应插入新的 locks 子文档,因为已经存在具有相同 unique_values$ne 部分的子文档查询应该导致它 return 没有要更新的匹配项。

我已经确认使用相同的查询 return 执行 find 在 MongoDB 命令行和使用 Mongoose 自己的 Schema.find 方法上都没有文档,但是Schema.update 方法仍然找到文档并插入重复的 lock 子文档。

我是快疯了还是 Mongoose 的 find 方法无法检索文档而 update 会检索文档?

问题是您正在查询对象是否与子文档匹配,这可能很棘手。你想做什么在你的查询中使用 $elemMatch 和 $ne 的组合。

var query = {
    _id: 'pickable_qty',
    'locks': { 
        $elemMatch: {
            merchant_warehouse_id: {
                $ne: 11.1
            },
            product_item_id: {
                $ne: 5334
            }
        }
    },
    'definition.unique_keys': { 
        '$all': [ 
            'merchant_warehouse_id', 
            'product_item_id' 
        ] 
    } 
}

它基本上是对数组内部文档的查询。

使用 MongoDB 的查询分析器后,我发现 Mongoose 在执行更新查询时正在切换 lockunique_values 对象中键的顺序。然后它以正确的顺序插入带有键的重复子文档。因此显然 MongoDB 的 $ne 运算符仅当子文档中的键与您的查询的顺序相同时才会匹配嵌套的子文档数组。