Get the index of this element in an array field in MongoDB

Think about this MongoDB document:

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

Question: How to get the position of mango in food?

The request should return 2 above and not return the entire document.

Please indicate a work request.

+6
source share
3 answers

Starting with version MongoDB 3.4, we can use the $indexOfArray operator to return the index at which the given element can be found in the array.

$indexOfArray takes three arguments. The first is the name of the array field with the $ prefix.

The second element, and the third optional is the index to start the search. $indexOfArray returns the first index in which the element is found if the index to start the search is not specified.


Demo:

 > 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 } 
+5
source

There is no other way ("server side") than using 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" } } ) 

This is the only thing that will return something else in a modified form different from the document itself, as well as using the necessary JavaScript evaluation to determine the answer,

Unfortunately, there is no "native" operator that will do this.

If you don’t need it for the real purposes of aggregation, then it’s best to do a similar “array index matching” in your client’s own code when working with "per document".

+4
source

In mongo shell (in Robomongo also) I would do the following:

  var food = db.getCollection('yourCollection').findOne({_id: '123'}).food; print('Index of mango: ' + food.indexOf('mango')); 

or you can save this code in any_file.js and then run from the command line:

  mongo your_db any_file.js 

This will produce something like this:

  MongoDB shell version: 2.4.9 connecting to: localhost:27017/your_db Index of mango: 2 
0
source

All Articles