gpt4 book ai didi

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

转载 作者:IT老高 更新时间:2023-10-28 13:13:35 25 4
gpt4 key购买 nike

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

我无法使用切片。这是我的意见:

{ "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”作为“相关性”数组的最后一个元素的行数。

有了上面的输入记录,应该是3。

最佳答案

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

更好的方法是使用 aggregate .但首先让我们考虑一下 $slice 是如何使用的:

> db.collection.find({},{ relevancy: {$slice: -1} })
{ "_id" : ObjectId("530824b95f44eac1068b45c0"), "relevancy" : [ "Y" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c2"), "relevancy" : [ "Y" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c3"), "relevancy" : [ "N" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c4"), "relevancy" : [ "Y" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c6"), "relevancy" : [ "N" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c7"), "relevancy" : [ "N" ] }
{ "_id" : ObjectId("530824b95f44eac1068b45c8"), "relevancy" : [ "N" ] }

所以你得到了最后一个数组元素,但是你被困在循环结果中,因为你不能匹配最后一个元素的值。您不妨在代码中完成此操作。

现在让我们看看聚合:

db.collection.aggregate([
// Match things so we get rid of the documents that will never match, but it will
// still keep some of course since they are arrays, that *may* contain "N"
{ "$match": { "relevancy": "Y" } },

// De-normalizes the array
{ "$unwind": "$relevancy" },

// The order of the array is retained, so just look for the $last by _id
{ "$group": { "_id": "$_id", "relevancy": { "$last": "$relevancy" } }},

// Match only the records with the results you want
{ "$match": { "relevancy": "Y" }},

// Oh, and maintain the original _id order [ funny thing about $last ]
{ "$sort": { "_id": 1 } }
])

即使这是您第一次使用 aggregate(),我也鼓励您学习它。它可能是您最有用的问题解决工具。当然是为了我。如果您正在学习,请将每个步骤一次一次

也不确定在您的文档表单上,所有 1: { ... } 子文档符号似乎都是错误的,但您应该清除它或调整上面的代码以引用 "1.relevancy" 代替。我希望您的文档实际上看起来更像这样:

{ "relevancy" : [  "Y" ] , "_id" : ObjectId("530824b95f44eac1068b45c0") }
{ "relevancy" : [ "Y", "Y" ] , "_id" : ObjectId("530824b95f44eac1068b45c2") }
{ "relevancy" : [ "N" ], "_id" : ObjectId("530824b95f44eac1068b45c3") }
{ "relevancy" : [ "Y", "Y" ], "_id" : ObjectId("530824b95f44eac1068b45c4") }
{ "relevancy" : [ "Y", "N" ], "_id" : ObjectId("530824b95f44eac1068b45c6") }
{ "relevancy" : [ "N" ], "_id" : ObjectId("530824b95f44eac1068b45c7") }
{ "relevancy" : [ "Y", "N" ], "_id" : ObjectId("530824b95f44eac1068b45c8") }

MongoDB 3.2.x 及更高版本

当然,MongoDB 3.2 为 $slice 引入了“聚合”运算符。还有一个更好的$arrayElemAt运算符消除了对任何 $unwind$group 处理的需要。在初始 $match 查询之后,您只需使用 $redact 进行“逻辑匹配” :

db.collection.aggregate([
{ "$match": { "relevancy": "Y" } },
{ "$redact": {
"$cond": {
"if": { "$eq": [{ "$arrayElemAt": [ "$relevancy", -1 ], "Y" ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}}
])

这将在从返回的结果中决定是 $$KEEP 还是 $$PRUNE 文档时检查数组的最后一个元素。

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

db.collection.aggregate([
{ "$match": { "relevancy": "Y" } },
{ "$redact": {
"$cond": {
"if": { "$eq": [{ "$arrayElemAt": [ "$relevancy", -1 ], "Y" ] },
"then": "$$KEEP",
"else": "$$PRUNE"
}
}},
{ "$project": { "relevancy": { "$slice": [ "$relevancy", -1 ] } } }
])

或替代方法:

db.collection.aggregate([
{ "$match": { "relevancy": "Y" } },
{ "$project": { "relevancy": { "$slice": [ "$relevancy", -1 ] } } },
{ "$match": { "relevancy": "Y" } }
])

但是首先执行 $redact 并“然后”在 `$project 中进行任何 reshape 可能成本更低。

关于mongodb - 使用 $slice 运算符获取数组的最后一个元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21952005/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com