如何在MongoDB中使用$slice和$filter结果?
我有以下格式的项目集合:如何在MongoDB中使用$slice和$filter结果?,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,我有以下格式的项目集合: { "_id": 123, "items": [{ "name": "item1", "status" : "inactive", "created" : ISODate("2018-02-14T10:39:28.321Z") }, { "name": "item2", "status" : "active", "created" : ISOD
{
"_id": 123,
"items": [{
"name": "item1",
"status" : "inactive",
"created" : ISODate("2018-02-14T10:39:28.321Z")
},
{
"name": "item2",
"status" : "active",
"created" : ISODate("2018-02-14T10:39:28.321Z")
},
{
"name": "item3",
"status" : "active",
"created" : ISODate("2018-02-14T10:39:28.321Z")
},
{
"name": "item4",
"status" : "inactive",
"created" : ISODate("2018-02-14T10:39:28.321Z")
},
{
"name": "item5",
"status" : "active",
"created" : ISODate("2018-02-14T10:39:28.321Z")
}
]
}
我想查询项目的状态字段,以便仅在数组中返回状态为“active”的对象,并在查询中返回skip last 1和limit 2
目前,我正在为此操作使用$filter(聚合),通过使用以下查询,它只返回最后一条记录:
db.item.aggregate([
{ "$match": { "items.status": "active" } },
{ "$project": {
"items": {
"$slice": [
{ "$filter": {
"input": "$items",
"as": "item",
"cond": { "$eq": [ "$$item.status", "active" ] }
}},
-1,2
]
}
}}
])
输出应为:
{
"_id": 123,
"items": [
{
"name": "item2",
"status" : "active",
"created" : ISODate("2018-02-14T10:39:28.321Z")
},
{
"name": "item3",
"status" : "active",
"created" : ISODate("2018-02-14T10:39:28.321Z")
}]
}
请帮助我实现此结果。一种方法是这样的(不需要$match阶段,具体取决于数据结构和索引设置,但出于性能原因,您可能仍希望保留它): 不过,我认为使用以下查询可能更好:
db.items.db.aggregate([
{
$project: {
"items": {
"$filter": {
"input": "$items",
"as": "item",
"cond": { "$eq": [ "$$item.status", "active" ] }
}
}
}
}, {
$project: {
"items": {
$slice: [
{
$slice: [
"$items",
{
$subtract: [ { $size: "$items" }, 1 ] // length of items array minus one
}
]
}, 2 // max two elements
]
}
}
}])
因为这一个将首先去掉最后一个元素,然后将输出限制为两个项目,这可能是在少于3个“活动”元素的情况下您想要的更多。如何将最后一个查询转换为PHP?我不再是PHP程序员(大约100年前我做过一些),所以我真的不知道。我也没有可用的PHP工作开发环境。但网上也有这样的例子:我用PHP转换了这个查询:但它给出了一个错误:
错误:localhost:27017:FieldPath字段名可能不是空字符串。
如果看不到您的代码,我就帮不上忙了。。。那可能是由任何原因造成的。。我可以建议您创建另一个SO问题吗?请检查:
db.items.db.aggregate([
{
$project: {
"items": {
"$filter": {
"input": "$items",
"as": "item",
"cond": { "$eq": [ "$$item.status", "active" ] }
}
}
}
}, {
$project: {
"items": {
$slice: [
{
$slice: [
"$items",
{
$subtract: [ { $size: "$items" }, 1 ] // length of items array minus one
}
]
}, 2 // max two elements
]
}
}
}])