Arrays MongoDB-查询数组的最后一个元素?

Arrays MongoDB-查询数组的最后一个元素?,arrays,mongodb,mongoose,mongodb-query,spring-data-mongodb,Arrays,Mongodb,Mongoose,Mongodb Query,Spring Data Mongodb,我知道MongoDB支持语法find{array.0.field:“value”},但我特别想对数组中的最后一个元素执行此操作,这意味着我不知道索引。有没有接线员,还是我运气不好 编辑:为了澄清,我希望find()只返回数组最后一个元素中的字段与特定值匹配的文档。使用$slice db.collection.find( {}, { array_field: { $slice: -1 } } ) 编辑: 你可以利用 {:{$elemMatch:{,…}}查找匹配项 但它不会给出你想要的东西。我认

我知道MongoDB支持语法
find{array.0.field:“value”}
,但我特别想对数组中的最后一个元素执行此操作,这意味着我不知道索引。有没有接线员,还是我运气不好


编辑:为了澄清,我希望find()只返回数组最后一个元素中的字段与特定值匹配的文档。

使用$slice

db.collection.find( {}, { array_field: { $slice: -1 } } )
编辑: 你可以利用
{:{$elemMatch:{,…}}
查找匹配项


但它不会给出你想要的东西。我认为这在mongoDB中还不可能。

我在官方的Mongo Google群组上发布了帖子,并从他们的工作人员那里得到了答案。看来我要找的是不可能的。我将使用一种不同的模式方法。

您可以在任何时候使用
$push
,然后始终查询
array.0
以获取最近添加的元素。当然,您将无法获得新的“last”元素

不确定性能,但这对我来说很有效:

db.getCollection('test')。查找(
{
$where:“this.someArray[this.someArray.length-1]==‘pattern’”
}
)

在3.2中,这是可能的。第一个项目,使myField只包含最后一个元素,然后匹配myField

db.collection.aggregate([
   { $project: { id: 1, myField: { $slice: [ "$myField", -1 ] } } },
   { $match: { myField: "myValue" } }
]);
您可以使用(3.6 mongo版本运算符)在常规查询中使用聚合函数

比较

对于标量数组

db.col.find({$expr: {$gt: [{$arrayElemAt: ["$array", -1]}, value]}})
对于嵌入式数组-使用带点符号的表达式投影最后一个元素

db.col.find({$expr: {$gt: [{"$arrayElemAt": ["$array.field", -1]}, value]}})
 db.col.find({$expr: {$gt: [{"$arrayElemAt": ["$array.field", -1]}, value]}})
Spring
@Query
code

@Query("{$expr:{$gt:[{$arrayElemAt:[\"$array\", -1]}, ?0]}}")
ReturnType MethodName(ArgType arg);

版本3.6使用聚合来实现相同的功能

db.getCollection('deviceTrackerHistory').aggregate([
   {
     $match:{clientId:"12"}
   },
   {
     $project:
      {
         deviceId:1,
         recent: { $arrayElemAt: [ "$history", -1 ] }
      }
   }
])

对于答案,如果我想要orderNumber:“12345”和最后一个元素的值$gt大于“value”,请使用
$arrayElemAt
?如何制作$expr?谢谢

对于嵌入式数组-使用带点符号的
$arrayElemAt
表达式投影最后一个元素

db.col.find({$expr: {$gt: [{"$arrayElemAt": ["$array.field", -1]}, value]}})
 db.col.find({$expr: {$gt: [{"$arrayElemAt": ["$array.field", -1]}, value]}})

启动
Mongo 4.4
,可以使用聚合运算符访问数组的最后一个元素:


例如,在
find
查询中:

// { "myArray": ["A", "B", "C"] }
// { "myArray": ["D"] }
db.collection.find({ $expr: { $eq: [{ $last: "$myArray" }, "C"] } })
// { "myArray": ["A", "B", "C"] }
db.collection.aggregate([
  { $addFields: { last: { $last: "$myArray" } } },
  { $match: { last: "C" } }
])

或在
聚合
查询中:

// { "myArray": ["A", "B", "C"] }
// { "myArray": ["D"] }
db.collection.find({ $expr: { $eq: [{ $last: "$myArray" }, "C"] } })
// { "myArray": ["A", "B", "C"] }
db.collection.aggregate([
  { $addFields: { last: { $last: "$myArray" } } },
  { $match: { last: "C" } }
])

您可以使用聚合来解决这个问题

model.aggregate([
    {
      $addFields: {
        lastArrayElement: {
          $slice: ["$array", -1],
        },
      },
    },
    {
      $match: {
        "lastArrayElement.field": value,
      },
    },
  ]);
快速解释
aggregate
创建一个顺序执行的操作管道,这就是它将数组作为参数的原因。首先,我们使用
$addFields
管道阶段。这在版本3.4中是新的,基本上意味着:保留文档的所有现有字段,但也添加以下内容。在本例中,我们添加了
lastArrayElement
,并将其定义为名为
array
的数组中的最后一个元素。接下来,我们执行
$match
管道阶段。此操作的输入是前一阶段的输出,其中包括新的
lastArrayElement
字段。这里我们要说的是,我们只包括其字段
字段
具有值
的文档



请注意,生成的匹配文档将包括
lastArrayElement
。如果出于某种原因,您确实不想这样做,您可以在
$match
之后添加一个
$project
管道阶段来删除它。

您的文档是什么样子的?我尝试测试的数组实际上嵌套在另一个数组中,但我认为这不会产生任何效果。基本上,我想做的是,在我的查找选择器中,只返回数组最后一个元素中的特定字段与特定值匹配的文档。您应该查看,然后使用最新的MongoDB使用
$unwind
$project
$match
$group
,您可以这样做:
查找({“数组。-1.字段”:“值”})
@MarsLee在4.2.0版上对我不起作用-你有更多的信息吗?这只是返回最后一个元素,对吗?这不是我想做的。我希望我的查找选择器只返回数组最后一个元素与某个值匹配的文档。请记住,$slice'返回数组,而“$arr”ayElemAt'返回一个文档(与sintax相同)。我考虑过这样做,但我的应用程序使用Spring数据访问Mongo,当时它不支持推到数组的前面。现在不确定是否支持。在3.2中有$arrayElemAt运算符,它与负索引一起工作。因此这可以改为
{$project:{id:1,myField:{$arrayElemAt:[“$myField”,-1]}
。我不知道一个只有一个元素的切片是否同样有效。这输出的结果正是问题所需要的。自从MongoDB v3.4以来,还有一个选项,这意味着您不再需要投影单个字段。$where非常慢,因为它运行javascriptThank!可能不是最有效的解决方案,但工作起来很有魅力对我来说。我的数据速度不太慢,可能这种性能差异只在大型数据集中可以察觉。错误做法@eagleeye。对于嵌入式阵列,为什么使用0而不是-1?这个解决方案对我很有效。我使用嵌入式阵列来检查阵列内的日期是否小于当前日期。如果小于我的upd读取文档。
const query={$expr:{$lt:[{$arrayElemAt:[“$lessons.studentData.dueDate”,-1]},new Date()};const update={completed:true};Class.updateMany(query,update)
db.col.find({$expr:{$gt:[{$arrayElemAt[“array”,-1]},value]})
为我抛出了一个错误。-->
db.col.find({$expr:{$gt:[{$arrayElemAt:[“$array”,-1]},value]})
感谢您的编辑;我尝试了几次,我想我已经解决了:``db.col.find({$expr:{$and:[{$gt:[{$arrayElemAt][$array::[$arrayElemAt[“$array.field”,-1]},value]},{$eq:[{$orderNumber”,$12345]})“这是2021年的正确答案!