我在数据库中有以下文档。我想要的是能够按数组内其子文档之一的值对文档进行排序。这可能吗?
{
name: "Item A",
subItems: [{
name: "Subitem 1",
value: 10
},
{
name: "Subitem 2",
value: 20
}]
},
{
name: "Item B",
subItems: [{
name: "Subitem 1",
value: 5
},
{
name: "Subitem 2",
value: 60
}]
}
我想按其中一个子项的值对文档进行排序,以使按升序排序的预期结果低于(在这种情况下,按降序排序也将得到相同的结果,因为项目B的价格最低且最大价值的商品)。我真的不在乎此查询中子项目的顺序,仅关心父文档的顺序。
预期结果:
{
name: "Item B",
subItems: [{
name: "Subitem 1",
value: 5
},
{
name: "Subitem 2",
value: 60
}]
},
{
name: "Item A",
subItems: [{
name: "Subitem 1",
value: 10
},
{
name: "Subitem 2",
value: 20
}]
}
我知道它将必须使用聚合,但不知道如何从此开始。任何帮助表示赞赏。
答案 0 :(得分:0)
取决于您在说什么值。
如果按数组本身进行排序,则在您按升序/降序排序时将使用最小值/最大值。只需:
db.coll.find({...}).sort({"subItems.0.value"})
任何索引都无法支持这种排序。
或者,您可以指定要用作排序键的元素:
db.coll.createIndex({"subItems.0.value": 1})
可以通过以下方式支持这种排序:
db.bar.aggregate([
{$match: {"subItems.value": {$lte: 10}}},
{$project: {
subItems: {
$filter: {
input: "$subItems",
as: "item",
cond: {
$lte: ["$$item.value", 10]
}
}
}
}},
{$sort: {"subItems.value": -1}}
])
如果以上都不是您想要的,我想您可能是想按某种条件过滤并按该元素排序。这可以通过使用聚合来实现:
$match
$filter运算符实际上是根据某种条件过滤元素的。之后,就像在场景1中按数组排序一样。
在此查询中,第一个{"subItems.value": 1}
可以利用索引$project
,而$sort
和{{1}}是纯CPU工作。
答案 1 :(得分:0)
这里有最简单的解决方案。
使用$min
聚合运算符查找subItems
数组中的最小值,然后$sort
与其一起使用
db.collection.aggregate([
{ "$addFields": {
"order": { "$min": "$subItems.value" }
}},
{ "$sort": { "order": 1 }}
])