3

我一直在寻找对集合中特定的内部数组进行排序,我在 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)可能不是一个好主意,最好有几个集合。所以保存参考。

4

1 回答 1

3

假设您的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
        }
    }}
)
于 2013-09-09T15:24:47.057 回答