我正在尝试编写一个 mongodb 聚合来应用 2 级排序,然后获取排序集中特定文档前后的 2 个文档。首先,我正在尝试为“之后”文档构建查询
文件乱序插入:
db.test.insertMany([
{ name: 'V', type: 'Trap' },
{ name: 'J', type: 'Magic' },
{ name: 'B', type: 'Effect' }
])
要在每个
type
内按字母顺序排序,我可以这样做:
db.test.aggregate([{ "$sort": { type: 1, name: 1 } }])
Result:
{ name: 'B', type: 'Effect' }
{ name: 'J', type: 'Magic' }
{ name: 'V', type: 'Trap' }
我正在尝试使用以下查询(带替换)来获取“之后”文档:
[
{ $sort: { type: 1, name: 1 } },
{
$match: {
name: {
$gt: <name>,
},
type: {
$gte: <type>,
},
},
},
{ $limit: 1 }
]
例如:
文件
{ name: 'K', type: 'Trap' }
应该在J和V之间。
文件
{ name: 'C', type: 'Effect' }
应该在B和J之间。
但是,document
{ name: 'K', type: 'Effect' }
也需要在 B 和 J 之间移动,因为它应该保留在“效果”分组中。
删除任何一个 $match 属性在其他情况下会给出不正确的结果。似乎也无法在所有情况下都使用 $and/or 来获得正确的结果
相反,我的“之前”查询如下(并非在所有情况下都有效):
{ $sort: { type: -1, name: -1 } },
{
$match: {
name: { $lt: card.name },
type: { $lte: card.type }
}
},
{ $limit: 1 }
可以编写一个匹配查询来检查
or
条件,其中检查 type
是否大于给定类型,或者如果类型等于给定类型,则检查 name
是否大于给定名称。要获取之前的文档,请将 gt
替换为 lt
db.collection.aggregate([
{ $sort: { type: 1, name: 1 } },
{
$match: {
$or: [
{ type: { $gt: <type> } },
{ $and: [{ type: <type> }, { name: { $gt: <name> } }] }
]
}
},
{ $limit: 1 }
])