排序数组和对象MongoDb数组

时间:2015-01-18 20:43:36

标签: arrays mongodb sorting

我有一个简单的Collection来理解MongoDB中的排序

我的文件是:

{
    "_id" : ObjectId("54b94985d74d670613e4fd35"),
    "tag" : [ 
        "A", 
        "B", 
        "Z"
    ]
}

{
    "_id" : ObjectId("54b949c9d74d670613e4fd36"),
    "tag" : [ 
        "D", 
        "E", 
        "F"
    ]
}

{
    "_id" : ObjectId("54b949dfd74d670613e4fd37"),
    "tag" : [ 
        "G", 
        "H", 
        "I"
    ]
}

当我按标签排序时我有这些结果

db.candy.find().sort({tag:1})


{
    "_id" : ObjectId("54b94985d74d670613e4fd35"),
    "tag" : [ 
        "A", 
        "B", 
        "Z"
    ]
}

{
    "_id" : ObjectId("54b949c9d74d670613e4fd36"),
    "tag" : [ 
        "D", 
        "E", 
        "F"
    ]
}

{
    "_id" : ObjectId("54b949dfd74d670613e4fd37"),
    "tag" : [ 
        "G", 
        "H", 
        "I"
    ]
}

而不是标签:-1

db.candy.find().sort({tag:-1})

{
    "_id" : ObjectId("54b94985d74d670613e4fd35"),
    "tag" : [ 
        "A", 
        "B", 
        "Z"
    ]
}

{
    "_id" : ObjectId("54b949dfd74d670613e4fd37"),
    "tag" : [ 
        "G", 
        "H", 
        "I"
    ]
}

{
    "_id" : ObjectId("54b949c9d74d670613e4fd36"),
    "tag" : [ 
        "D", 
        "E", 
        "F"
    ]
}

结果非常相似,第一个对象是相同的,只改变第二个和第三个。 与对象数组相同的结果。 我的问题是: 它是如何工作的那种? 我知道字母A是字母(ASCII CODE)的第一个字母,Z是最后一个字母。 mongo检查数组的每个元素(或对象)? 当我使用tag:-1和tag:1时,为什么数组内部的顺序是相同的?我期待像

这样的东西

标签:1

{
    "_id" : ObjectId("54b94985d74d670613e4fd35"),
    "tag" : [ 
        "A", 
        "B", 
        "Z"
    ]
}

并标记:-1

{
    "_id" : ObjectId("54b94985d74d670613e4fd35"),
    "tag" : [ 
        "Z", 
        "A", 
        "B"
    ]
}

2 个答案:

答案 0 :(得分:4)

按数组字段排序文档时的

排序运算符,执行以下操作:

  1. 按降序排序时,它会占用每个数组中最大的元素并与其他数组进行比较

  2. 当升序排序时,它会从每个数组中获取最小元素并与其他元素进行比较

  3. 这些仅用于对文档进行排序,这就是为什么文档中的顺序是相同的

      

    对于数组,小于比较或升序排序比较   数组的最小元素,大于比较或a   降序排序比较数组的最大元素。因此,   比较一个值为单元素数组的字段(例如[1   ])对于非数组字段(例如2),比较在1和2之间。   空数组(例如[])的比较将空数组视为   小于null或缺少字段。

    http://docs.mongodb.org/manual/reference/method/cursor.sort/

答案 1 :(得分:1)

只是重复一遍并详细说明@marcinn,回答。

当发出以下语句时,它会向mongodb sort询问传递给find()语句的查询所找到的文档,在本例中是所有文档中的文档。收集将由find()函数返回tag字段。

此处需要注意的是,字段tag的类型为array,而不是简单的字段。

db.candy.find().sort({tag:1})

如果是简单字段,则文档将按tag字段中的值进行排序。

无论如何,mongodb需要一个可以对文档进行排序的值。为了获得该字段的值,mongodb执行以下操作:

  • 检查tag是否为数组。如果是数组,则需要选择一个 数组中的元素,其值可以假设为权重 特别文件。
  • 现在检查指定的排序是升序还是降序 顺序。
  • 如果它按升序排列,它会找到标签中的最小元素 数组,否则最大。
  • 使用从标签数组中选择的元素,对于每个文档, 排序已应用。

这里需要注意的一点是,排序操作只会改变检索到的 root 文档的顺序,换句话说,它就像{{1}中的order by子句一样条款。

更改每个文档的标记数组元素的顺序。

根据经验,SQL查询与find()limit操作链接在一起,不会更改检索到的文档的结构。要操纵您需要执行聚合操作的文档结构。

您在问题中的期望是通过操纵每个文档中的字段来实现的,而这些字段只能进行聚合操作。

因此,如果将其汇总为,

sort

然后你可以得到你的结果:

db.candy.aggregate([
{$match:{"_id":ObjectId("54b94985d74d670613e4fd35")}},
{$unwind:"$tag"},
{$sort:{"tag":-1}},
{$group:{"_id":"$_id","tag":{$push:"$tag"}}}
])