MongoDB:对数组元素进行匹配和排序?

大卫·艾尔纳(David Elner)

我有一些“产品”对象:

{ name: 'ProductA',
  social_stats: [
    { name: 'facebook',
      shares: 60
    },
    { name: 'twitter',
      shares: 0
    }
  ]
}

{ name: 'ProductB',
  social_stats: [
    { name: 'facebook',
      shares: 0
    },
    { name: 'twitter',
      shares: 30
    }
  ]
}

我想查询“ Facebook上共享最多的产品”和“ Twitter上共享最多的产品”,它们总是按共享程度从高到低排序。

因此,我对Facebook的第一个查询如下所示:

db.videos.find({
  _id: {
    social_stats: {
      $elemMatch: {
        name: 'facebook'
      }
    }
  }
).sort( {
  social_stats: {
    shares: -1
  }
})

产量:

{ name: 'ProductA' }
{ name: 'ProductB' }

这是“正确的”,但是当我对“ twitter”运行相同的查询时,我期望的是B-> A,但收到的输出与上述相同。它似乎没有按我的意图一起应用where和sort逻辑,即“按与'twitter'相匹配的social_stat元素进行排序”。

我在寻找什么

  • 如何更改查询以反映order()对匹配的social_stat元素的应用?
  • 如果这些普通的MongoDB查询无法实现,那么我可以使用聚合框架来做这件事吗?那会是什么样子?
  • 然后,作为奖励,如何用Mongoid编写等效查询?

我看过的一些相关链接:

斯坦尼

您无法sort()通过数组来获得结果,因此这将无法实现您所追求的结果。

最好的方法(从MongoDB 2.4开始)是使用Aggregation Framework:

db.videos.aggregate(
    // Optional: potentially take advantage of an index to only find videos with
    //           facebook stats; could also limit to those with shares $gt 0
    { $match: {
        'social_stats.name' : 'facebook'
    }},

    // Convert the social_stats array into a document stream
    { $unwind: '$social_stats' },

    // Only match the social stats for facebook
    { $match: {
        'social_stats.name' : 'facebook'
    }},

    // Sort in descending order
    { $sort: {
        'social_stats.shares' : -1
    }},

    // Only include the product names & score
    { $project: {
        _id: 0,
        name: "$name",
        shares: "$social_stats.shares"
    }}
)

“ twitter”的结果:

{
    "result" : [
        {
            "name" : "ProductB",
            "shares" : 30
        },
        {
            "name" : "ProductA",
            "shares" : 0
        }
    ],
    "ok" : 1
}

“ facebook”的结果:

{
    "result" : [
        {
            "name" : "ProductA",
            "shares" : 60
        },
        {
            "name" : "ProductB",
            "shares" : 0
        }
    ],
    "ok" : 1
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章