$ min和$ max在嵌入式文档内部如何工作?

时间:2019-10-01 11:35:26

标签: mongodb aggregation-framework

比方说,我最初在DB中有以下文档:

{
    "_id" : ObjectId("5d932facf2e6411a68a145e8"),
    "name" : "mechanic",
    "value" : {
        "a" : 1,
        "b" : 2
    }
}
{
    "_id" : ObjectId("5d932facf2e6411a68a145e9"),
    "name" : "mechanic",
    "value" : {
        "a" : 2,
        "b" : 1
    }
}
{
    "_id" : ObjectId("5d932facf2e6411a68a145ea"),
    "name" : "mechanic",
    "value" : {
        "a" : 0,
        "b" : 3
    }
}
{
    "_id" : ObjectId("5d9332eff2e6411a68a145ec"),
    "name" : "mechanic",
    "value" : {
        "a" : 0,
        "b" : 2
    }
}

当我运行以下查询时:

db.collection.aggregate([ { $group:{ "_id":"$name", "min_doc":{ $min:"$value" } } } ]).pretty()

它返回:

{ "_id" : "mechanic", "min_doc" : { "a" : 0, "b" : 2 } }

似乎,它逐个比较子文档value的关键字,即找到最小值'a',如果多个文档的最小值为'a',则查找最小值'b'。

但是,然后我又添加了一个文档:

{
    "_id" : ObjectId("5d933330f2e6411a68a145ed"),
    "name" : "mechanic",
    "value" : {
        "b" : 1,
        "a" : 0
    }
}

它返回相同的输出。但是最后一个文档的'a'和'b'最低。

它在内部如何工作?

1 个答案:

答案 0 :(得分:1)

https://docs.mongodb.com/manual/reference/operator/aggregation/min/

  

$ min使用指定的BSON比较顺序对不同类型的值进行比较,同时比较值和类型。

由于$value是对象,因此Mongo遵循以下说明:

MongoDB对BSON对象的比较使用以下顺序:

  1. 递归地比较键值对在BSON对象中的显示顺序。
  2. 比较关键字段名称。
  3. 如果关键字段名称相等,请比较字段值。
  4. 如果字段值相等,则比较下一个键/值对(返回步骤1)。没有其他对的对象小于具有其他对的对象。

说明

  1. MongoDB从所有文档中选择第一个存储的对象密钥。
  2. 比较键。对于字符串,使用二进制比较。如果相等,则下一步
  3. 比较值。对于字符串,使用二进制比较。如果相等,则下一步
  4. 重复步骤1,除非an object without further pairs is less than an object with further pairs

================================================ =================

“按照它们出现在BSON对象中的顺序”是什么意思

让我们稍作更改:(按键顺序)

{
    "_id" : ObjectId("5d932facf2e6411a68a145e8"),
    "name" : "mechanic",
    "value" : {
        "b" : 0, <-- 1st key
        "a" : 0  <-- 2nd key
    }
}
{
    "_id" : ObjectId("5d932facf2e6411a68a145e9"),
    "name" : "mechanic",
    "value" : {
        "a" : 100, <-- 1st key
        "b" : 100  <-- 2nd key
    }
}

逻辑上,最小值为{"b" : 0, "a" : 0},但这取决于键的存储顺序。

由于a小于b,最小值为:

{
    "_id" : "mechanic",
    "min_doc" : {
        "a" : 100,
        "b" : 100
    }
}

如果我们更改第一个文档ab的顺序,则最小值将更改:

{
    "_id" : "mechanic",
    "min_doc" : {
        "a" : 0,
        "b" : 0
    }
}

来源:https://docs.mongodb.com/manual/reference/bson-type-comparison-order/#objects