如何在MongoDB中保持订单?

如何在MongoDB中保持订单?,mongodb,Mongodb,在我的MongoDB文档中,有这样的对象 [_id] => MongoId Object ( [$id] => 52a46b44aabacb5c218b4567 ) [results] => Array ( [http://google.com] => Array ( [position] => 1 [data] => 42672 ) [http://bing.com] => Array (

在我的MongoDB文档中,有这样的对象

[_id] => MongoId Object (
    [$id] => 52a46b44aabacb5c218b4567
)
[results] => Array (
    [http://google.com] => Array (
        [position] => 1
        [data] => 42672
    )
    [http://bing.com] => Array (
        [position] => 2
        [data] => 9423
    )
    [http://yandex.com] => Array (
        [position] => 3
        [data] => 5513
    )
)
[_id] => MongoId Object (
    [$id] => 52a46b44aabacb5c218b4567
)
[results] => Array (
    [http://google.com] => Array (
        [position] => 1
        [data] => 42672
    )
    [http://bing.com] => Array (
        [position] => 2
        [data] => 300
    )
    [http://yandex.com] => Array (
        [position] => 3
        [data] => 5513
    )
)
我想将“bing.com”中的数据参数从9423更改为例如300。此外,我必须保持网站的秩序。一定是这样的

[_id] => MongoId Object (
    [$id] => 52a46b44aabacb5c218b4567
)
[results] => Array (
    [http://google.com] => Array (
        [position] => 1
        [data] => 42672
    )
    [http://bing.com] => Array (
        [position] => 2
        [data] => 9423
    )
    [http://yandex.com] => Array (
        [position] => 3
        [data] => 5513
    )
)
[_id] => MongoId Object (
    [$id] => 52a46b44aabacb5c218b4567
)
[results] => Array (
    [http://google.com] => Array (
        [position] => 1
        [data] => 42672
    )
    [http://bing.com] => Array (
        [position] => 2
        [data] => 300
    )
    [http://yandex.com] => Array (
        [position] => 3
        [data] => 5513
    )
)
这在Mongo是可以实现的吗

我非常确定(和其他数据库管理系统一样),您不能也不应该依赖记录顺序


相反,我建议您添加
索引
(在
位置
,即
db.people.ensureIndex({position:1})
)并查询按该字段排序的记录,即。e、 :
db.collection.find()

我注意到您最初将站点列表建模为一个嵌入文档,但是嵌入文档中字段的顺序目前不能保证保留,因此您应该使用数组

此外,您不能在MongoDB中使用带有嵌入点(.)的字段名,因此您不应该计划将URL存储为字段名(请参阅:)

为了在数组中查找元素,您需要按值(而不是字段名)进行搜索,因此您的模式应该更像:

{
    _id: ObjectId("52a46b44aabacb5c218b4567"),
    results: [
        {
            site: 'http://google.com',
            position: 1,
            data: 42762
        },
        {
            site: 'http://bing.com',
            position: 2,
            data: 9423
        },
        {
            site: 'http://yandex.com',
            position: 3,
            data: 5513
        }
    ]
}
假设数组
site
元素是唯一的,您可以使用查找并更新匹配的嵌入文档

例如,要更新“bing.com”
数据
值:

db.sites.update(
    // Match criteria
    {
        _id:ObjectId("52a46b44aabacb5c218b4567"),
        'results.site':'http://bing.com'
    },
    // Update
    { $set: {
        'results.$.data': 300 }
    }
)
在MongoDB 2.4+中,当您添加新条目时,您可以选择该选项,这也是一种有用的方法来维护数组的排序顺序

值得注意的是,如果您计划在一个数组中存储多个(即数千个)项,那么由于文档增长和更新大型数组的复杂性,这可能会造成严重的性能损失。

自MongoDB v2.5.2(2.6版)起,字段的重新排序已得到修复。话虽如此,完全避免问题的一种方法是将结果作为数组而不是(子)文档。还请注意,您也不应将“.”用作密钥名称的一部分。 在2.4中,您将看到在_id=1(子文档)的情况下有重新排序,但在_id=2(数组)的情况下没有重新排序


是的。这里:我认为您必须与位置操作符一起工作:我不确定我是否理解得很好。有没有办法让Mongo对对象进行预排序?你能给我举个例子吗?我认为Helid的查询返回一个文档,其中包含他或她想要保留的数组,你是对的。我必须将URL保持在它们的位置(如果我想更新[数据]),我需要对所有内容进行排序以显示结果。我可以用php对其进行排序并进行更新,但速度不如我预期的快。如果mongo能够维持秩序,我会很高兴。我已经安装了MongoDB 2.5.2,之后mongo不再更新,而是将数据推送到阵列。我想问题是URL中有一个“点”。