I Have a document like this
...
"users" : [
{
"name":"Bob"
},
{
"name":"Foo"
},
{
"name":"Bar"
},
{
"name":"Boo"
}
]
...
And I want Find the index of Bar
db.coll.find({"users.name":"Bar"})
Can I retrieve the Index of Bar inside Users array? (in this case : 2)
I really don't think the question you are asking leads to the actual answer that you want, but I'll run through a few things to clear up some misconceptions.
Operations such as .find() only returns the "fields present" in the document. It does not create "new results" in any way. The only present exception is the $meta operation which currently only has "textScore" when used with the $text operator for a text search.
There is a positional $ operator, which does "hold" the "matched" position of the first matched array element. But this value itself cannot be "projected" and is only used as a placeholder in order to return an array element at that matching position:
db.collection.find({ "users.name": "Bar" }, { "users.$": 1 })
Which just returns the matching element from the array and no other elements.
In order to get the actual matching position you generally need to inspect the array in code in order to find the matching index position. So retrieve the document and then inspect the array to find the matching index.
If you want to do this over multiple documents then you pretty much do the same thing wrapped in a mapReduce operation. For a full example working with mongoose:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/test');
var userFieldSchema = new Schema({
name: String
},{ "_id": false });
var userSchema = new Schema({
users: [userFieldSchema]
});
var User = mongoose.model( "User", userSchema, "users" );
var value = "Bar";
var o = {};
o.map = function() {
emit( this._id, this.users.map(
function(x) { return x.name == value }).indexOf(true)
);
};
o.reduce = function(){};
o.query = { "users.name": value };
o.scope = { value: value };
User.mapReduce(o, function(err,results) {
if ( err ) throw err;
console.log( results );
});
Where the results returned are the _id of the documents matching the condition and the corresponding matching "index" value from the array being tested.
Only operations such as mapReduce and aggregate actually "change" the content of the documents they are working on in the returned result. So there is no present implementation that allows this to be possible with operations such as .find().