0

我正在使用 Mongodb,但我可以迁移到 mysql,我的问题是,我有一个包含这样的数据的集合,

array(
"L"=>"cars",
"M"=>"wolkswagen"
)
array(
"L"=>"cars",
"M"=>"bmw"
)
array(
"L"=>"cars",
"M"=>"mercedes"
)


array(
"L"=>"bike",
"M"=>"bianchi"
)
array(
"L"=>"bike",
"M"=>"trek"
)
array(
"L"=>"bike",
"M"=>"brook"
)

结果我想得到什么,任何自行车和汽车,但每个都有 2 个结果,所以结果应该是,

array(
"L"=>"cars",
"M"=>"some car"
)
array(
"L"=>"cars",
"M"=>"some car"
)


array(
"L"=>"bike",
"M"=>"some bike"
)
array(
"L"=>"bike",
"M"=>"some bike"
)

我试图用 $in 来做这件事,但似乎没有用,有什么想法吗?

4

1 回答 1

1

使用MongoDB 2.2+ 中的聚合框架有几种方法可以解决这个问题。

不幸的是,2.2.2 的聚合框架还不支持$sliceor 数组子集运算符,因此需要一些额外的操作。

注意:下面的示例使用mongoshell,但应该可以直接转换为 PHP 驱动程序。

示例 #1:使用聚合框架提取两个匹配项(第一个和最后一个)

假设您不为每个分组获得哪两个元素而烦恼,您可以选择$firstand $last

db.cars.aggregate(

    // Group by $L and find the first and last elements
    { $group: {
        _id: '$L',
        first: { $first: "$M" },
        last: { $last: "$M" },
    }},

    // Add an extra $index for # of array elements
    { $project: {
        first: 1,
        last: 1,
        index: { $const:[0,1] }     
    }},

    // Split into document stream based on $index
    { $unwind: '$index' },

    // Re-group data using conditional to create array 
    { $group: {
        _id: '$_id',
        M: {
            $push: { $cond:[ {$eq:['$index', 0]}, '$first', '$last'] }
        }
    }}
)

样本输出:

{
    "result" : [
        {
            "_id" : "cars",
            "M" : [
                "wolkswagen",
                "mercedes"
            ]
        },
        {
            "_id" : "bike",
            "M" : [
                "bianchi",
                "brook"
            ]
        }
    ],
    "ok" : 1
}

示例#2:使用聚合框架创建一个集合,然后减少

上述方法的替代方法是使用更简单的管道$addToSet和后处理步骤来修剪数组元素:

var agg = db.cars.aggregate(
    { $group: {
        _id: '$L',
        'M': { $addToSet: "$M" },
    }}
)

// Iterate to trim each result to the desired # of elements
agg.result.forEach(function(doc) {
    // Note: you could randomly select 2 (or n) elements here
    doc.M = doc.M.slice(0,2);
})

输出格式将与示例 #1 相同,但示例 #2(如所写)选择前两个元素,而不是选择第一个和最后一个元素。

于 2013-01-04T13:29:37.133 回答