【问题标题】:How sort an array in a collection如何对集合中的数组进行排序
【发布时间】:2013-09-06 10:28:41
【问题描述】:

我一直在寻找对集合中的特定内部数组进行排序,我在 symfony2 中使用了学说-mongodb-bundle。 我的收藏:

"page":
{
    "_id": "56rgt46rt54h68rt4h6"
    "categories":
    [{
        "_id": "2g56rt1h65rt165165erg4"
        "products":[
            {"name":"A", "pos": 2},
            {"name":"B", "pos": 7},
            {"name":"C", "pos": 1},
            {"name":"D", "pos": 5}
        ]
    }]
}

我希望我有:

"page":
{
    "_id": "56rgt46rt54h68rt4h6"
    "categories":
    [{
        "_id": "2g56rt1h65rt165165erg4"
        "products":[
            {"name":"C", "pos": 1},
            {"name":"A", "pos": 2},
            {"name":"D", "pos": 5},
            {"name":"B", "pos": 7}
        ]
    }]
}

还有我的实体:

/**
 * @MongoDB\EmbeddedDocument
 */
class Category
{
    /**
     * @MongoDB\Id(strategy="auto")
     */
    protected $id;

    /**
     * @MongoDB\String
     */
    protected $name;

    /** @MongoDB\EmbedMany(targetDocument="\Document\Product") */
    private $products = array();
}

/**
 * @MongoDB\EmbeddedDocument
 */
class Product
{
    /**
     * @MongoDB\Int
     */
    protected $pos;

    /**
     * @MongoDB\String
     */
    protected $name;
}

我是 DoctrineMongoDBBundle 的新手,累积内部数组(EmbedMany)可能不是一个好主意,最好有几个集合。所以保存参考。

【问题讨论】:

  • 你真的需要考虑重新设计你的模式来利用 Mongo 的排序。或者通过定义自己的排序顺序在客户端进行。

标签: mongodb symfony doctrine-mongodb


【解决方案1】:

假设您的 products 数组中的项目是唯一的,那么在 MongoDB 2.4 中并没有任何简单的服务器端支持以按排序顺序维护此数组。给定嵌套数组的最佳选择是在应用程序逻辑中对数组进行适当的排序(即在插入/更新时,或在检索/显示时)。

数据建模注意事项

如果您需要对嵌套数组条目进行大量操作,则应考虑将数据模型展平以使其更易于使用。您对 MongoDB 的设计目标应该是拥有一个适合您的应用程序用例的数据模型,并在易于插入/更新/查询之间取得可接受的性能平衡。如果这样做没有意义,您绝对不必在单个集合/查询中对所有内容进行建模,并且您应该准备好对数据进行非规范化(重复)。对于产品 类别等多对多关系,通常会嵌入和非规范化更新频率较低的实体(例如,在产品中嵌入类别)。

持久化排序、封顶数组(非唯一项)

如果您想按排序顺序保存数组并且项目不是唯一的,MongoDB 2.4 确实可以选择 $push 到排序数组,但这必须与切片结合使用(数组限制)。如果您 $push 排序数组的相同条目,您最终会得到重复项(因此这可能不是您所追求的)。

示例更新,假设您的示例中的 page 是集合名称:

db.page.update(
    // Query
    { "_id": "56rgt46rt54h68rt4h6" },

    // Update sorted array
    // NB: referring by array index position 0, as there isn't a named reference
    { $push : {
        "categories.0.products" : { 

            // List of new elements to push
            $each : [
                { "name" : "E", "pos": 3 }
            ],

            // Sort by pos (ascending)
            $sort : { "pos" : 1 },

            // Maximum number of array elements (required for $sort)
            $slice : -100
        }
    }}
)

【讨论】:

猜你喜欢
  • 2016-07-12
  • 2017-11-20
  • 2014-08-29
  • 2011-04-04
  • 2016-08-28
  • 1970-01-01
  • 2017-11-01
  • 1970-01-01
相关资源
最近更新 更多