想想这个MongoDB文档:
{_id:123, "food":[ "apple", "banana", "mango" ]}
问题:如何得到食品中mango
的位置?
查询应该返回上面的2
,而不是返回整个文档。
Please Please show working query.
从MongoDB 3.4版本开始,我们可以使用$indexOfArray
运算符返回数组中给定元素的索引。
$indexOfArray
接受三个参数。第一个是数组字段的名称,前缀为$
。
第二个是元素,第三个可选的是开始搜索的索引。如果没有指定开始搜索的索引,则$indexOfArray
返回找到该元素的第一个索引。
演示:
> db.collection.insertOne( { "_id" : 123, "food": [ "apple", "mango", "banana", "mango" ] } )
{ "acknowledged" : true, "insertedId" : 123 }
> db.collection.aggregate( [ { "$project": { "matchedIndex": { "$indexOfArray": [ "$food", "mango" ] } } } ] )
{ "_id" : 123, "matchedIndex" : 1 }
> db.collection.aggregate( [ { "$project": { "matchedIndex": { "$indexOfArray": [ "$food", "mango", 2 ] } } } ] )
{ "_id" : 123, "matchedIndex" : 3 }
> db.collection.aggregate( [ { "$project": { "matchedIndex": { "$indexOfArray": [ "$food", "apricot" ] } } } ] )
{ "_id" : 123, "matchedIndex" : -1 }
除了使用mapReduce
:
db.collection.mapReduce(
function() {
emit(this._id, this.food.indexOf("mango"));
},
function() {}, // reducer never gets called since all _id is unique
{
"out": { "inline": 1 },
"query": { "food": "mango" }
}
)
这是唯一会以文档本身以外的修改形式返回其他内容的东西,以及使用所需的JavaScript计算来确定答案,
不幸的是,没有"本机"操作符可以做到这一点。
除非您需要这样做用于真正的聚合目的,否则在以"每个文档"为基础处理时,最好在客户端的本机代码中执行类似的"数组索引匹配"。
在mongo shell中(也在Robomongo中),我会做以下操作:
var food = db.getCollection('yourCollection').findOne({_id: '123'}).food;
print('Index of mango: ' + food.indexOf('mango'));
或者您可以将此代码保存在any_file.js
中,然后从命令行运行:
mongo your_db any_file.js
结果如下:
MongoDB shell version: 2.4.9
connecting to: localhost:27017/your_db
Index of mango: 2