获取MongoDB中数组字段中给定元素的索引

时间:2015-10-13 10:50:51

标签: mongodb mapreduce mongodb-query aggregation-framework

想想这个MongoDB文档:

{_id:123, "food":[ "apple", "banana", "mango" ]}

问题:如何获得mango在食物中的位置?

查询应在上方返回2,并且不会返回整个文档。

请显示正在运行的查询。

3 个答案:

答案 0 :(得分:5)

从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 }

答案 1 :(得分:4)

除了使用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评估来确定答案,

遗憾的是没有"本地人"将要执行此操作的运算符。

除非你需要这个用于真正的聚合目的,否则最好只做一个类似的"数组索引匹配"在处理"每个文档时,在客户端的本机代码中#34;基础。

答案 2 :(得分:0)

在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