Mongodb 使用$slice运算符获取数组的最后一个元素

Mongodb 使用$slice运算符获取数组的最后一个元素,mongodb,mongodb-query,aggregation-framework,Mongodb,Mongodb Query,Aggregation Framework,如何根据mongodb中的条件获取数组的最后一个元素 我不能用slice。以下是我的意见: { "1" : { "relevancy" : [ "Y" ] } } { "1" : { "relevancy" : [ "Y", "Y" ] } } { "1" : { "relevancy" : [ "N" ] } } { "1" : { "relevancy" : [ "Y", "Y" ] } } { "1" : { "relevancy" : [ "Y", "N" ] } } {

如何根据mongodb中的条件获取数组的最后一个元素

我不能用slice。以下是我的意见:

{ "1" : { "relevancy" : [  "Y" ] } }
{ "1" : { "relevancy" : [  "Y",  "Y" ] } }
{ "1" : { "relevancy" : [  "N" ] } }
{ "1" : { "relevancy" : [  "Y",  "Y" ] } }
{ "1" : { "relevancy" : [  "Y",  "N" ] } }
{ "1" : { "relevancy" : [  "N" ] } }
{ "1" : { "relevancy" : [  "Y",  "N" ] } }
我想计算将“Y”作为“relevance”数组的最后一个元素的行数


对于上面的输入记录,它应该是3。

正如您现在所知道的,仅在投影中用于限制结果中返回的数组元素。因此,您将不得不使用find()的结果以编程方式处理列表

更好的方法是使用。但是首先让我们考虑如何使用$切片:

>db.collection.find({},{relevance:{$slice:-1}})
{“_id”:ObjectId(“530824b95f44eac1068b45c0”),“相关性”:[“Y”]}
{“_id”:ObjectId(“530824b95f44eac1068b45c2”),“相关性”:[“Y”]}
{“_id”:ObjectId(“530824b95f44eac1068b45c3”),“相关性”:[“N”]}
{“_id”:ObjectId(“530824b95f44eac1068b45c4”),“相关性”:[“Y”]}
{“_id”:ObjectId(“530824b95f44eac1068b45c6”),“相关性”:[“N”]}
{“_id”:ObjectId(“530824b95f44eac1068b45c7”),“相关性”:[“N”]}
{“_id”:ObjectId(“530824b95f44eac1068b45c8”),“相关性”:[“N”]}
因此,您得到了最后一个数组元素,但由于无法匹配最后一个元素的值,因此您必须循环结果。您最好在代码中完成这项工作

现在让我们看一下聚合:

db.collection.aggregate([
//匹配一些东西,这样我们就可以去掉那些永远不会匹配的文档,但它会匹配的
//当然,仍然保留一些,因为它们是数组,*可能*包含“N”
{“$match”:{“相关性”:“Y”},
//反规范化数组
{“$unwind”:“$relevance”},
//数组的顺序被保留,因此只需查找$last by\u id即可
{“$group”:{“\u id”:“$\u id”,“相关性”:{“$last”:“$relevancy”}},
//仅将记录与所需结果进行匹配
{“$match”:{“相关性”:“Y”},
//哦,保持原始的身份证订单[关于上次$last的有趣事情]
{“$sort”:{“\u id”:1}
])
即使这是您第一次使用aggregate(),我也鼓励您学习它。它可能是你最有用的解决问题的工具。当然是对我来说。如果您正在学习,请将每一步一次进行一次

也不确定在您的文档表单上,所有的
1:{…}
子文档符号似乎都是错误的,但是您应该清除该错误,或者将上面的代码调整为引用
“1.relevance”
。我希望您的文档看起来更像这样:

{“相关性”:[“Y”],“_id”:ObjectId(“530824b95f44eac1068b45c0”)}
{“相关性”:[“Y”,“Y”],“_id”:ObjectId(“530824b95f44eac1068b45c2”)}
{“相关性”:[“N”],“_id”:ObjectId(“530824b95f44eac1068b45c3”)}
{“相关性”:[“Y”,“Y”],“_id”:ObjectId(“530824b95f44eac1068b45c4”)}
{“相关性”:[“Y”,“N”],“_id”:ObjectId(“530824b95f44eac1068b45c6”)}
{“相关性”:[“N”],“_id”:ObjectId(“530824b95f44eac1068b45c7”)}
{“相关性”:[“Y”,“N”],“_id”:ObjectId(“530824b95f44eac1068b45c8”)}

MongoDB 3.2.x及以上版本 当然,MongoDB 3.2引入了一个“聚合”操作符和一个更好的操作符,它不需要任何
$unwind
$group
处理。在初始
$match
查询之后,您只需与以下对象进行“逻辑匹配”:

db.collection.aggregate([
{“$match”:{“相关性”:“Y”},
{“$redact”:{
“$cond”:{
“if”:{“$eq”:[{“$arrayElemAt”:[“$relevance”,-1],“Y”},
“然后”:“$$KEEP”,
“else”:“$$PRUNE”
}
}}   
])
这将在决定是从返回的结果中
$$KEEP
还是
$$PRUNE
文档时检查数组的最后一个元素

如果您仍然需要“投影”,那么实际上可以添加
$slice

db.collection.aggregate([
{“$match”:{“相关性”:“Y”},
{“$redact”:{
“$cond”:{
“if”:{“$eq”:[{“$arrayElemAt”:[“$relevance”,-1],“Y”},
“然后”:“$$KEEP”,
“else”:“$$PRUNE”
}
}},
{“$project”:{“relevance”:{“$slice”:[“$relevance”,-1]}
])
或以下替代方法:

db.collection.aggregate([
{“$match”:{“相关性”:“Y”},
{“$project”:{“relevance”:{“$slice”:[“$relevance”,-1]},
{“$match”:{“相关性”:“Y”}
])

但是首先执行
$redact
并“然后”在“$project”中执行任何重新整形的成本可能更低。

Mongo 4.4
开始,聚合运算符可用于访问数组的最后一个元素:

// { "1": { "relevancy": ["Y"] } }
// { "1": { "relevancy": ["Y", "Y"] } }
// { "1": { "relevancy": ["N"] } }
// { "1": { "relevancy": ["Y", "Y"] } }
// { "1": { "relevancy": ["Y", "N"] } }
// { "1": { "relevancy": ["N"] } }
// { "1": { "relevancy": ["Y", "N"] } }
db.collection.aggregate([
  { $project: { last: { $last: "$1.relevancy" } } },
  // { "last": "Y" }
  // { "last": "Y" }
  // { "last": "N" }
  // { "last": "Y" }
  // { "last": "N" }
  // { "last": "N" }
  // { "last": "N" }
  { $match: { "last": "Y" } },
  // { "last": "Y" }
  // { "last": "Y" }
  // { "last": "Y" }
  { $count: "result" }
  // { "result" : 3 }
])