Tiago Redaelli
Tiago Redaelli

Reputation: 620

How to query elements inside an array?

How do i query any objects whos array contains a player with a matching case-insensitive name? db.collection.find(players.name: search)

This is a example object of how the data is stored (I've removed all irrelevant fields to the question).

{ "_id" : ObjectId("5d67f29ae6504b451c3aca3e"), "players" : [
 { "name" : "Jenny"}, { "name" : "Benny"}, { "name" : "Kenny" } ] }

One solution would be to just iterate through all documents in the collection and then in turn iterate through all names in each document but I'm trying to avoid this. Another is perhaps to map names to objectIds?

Upvotes: 0

Views: 315

Answers (3)

Juanín
Juanín

Reputation: 851

You can use a regex to do this:

db.collection.find("players.name": {'$regex' : '^string$', '$options' : 'i'})

Upvotes: 1

Tiago Redaelli
Tiago Redaelli

Reputation: 620

Thanks $elemMatch was indeed the solution.

dbo.collection('replays').find({ players: {
        $elemMatch: {name : {$regex: new RegExp('^'+ search + '$', "i") }} 
    }
}).toArray(function (err, res) {
    console.log(res);
});

Upvotes: 0

Holli
Holli

Reputation: 5072

Here's my, apparently more traditional, take on it. I didn't know a construct like your own answer here uses exists in the language, I have to do some reading. Anyway, here we go.

function find_player( data, player_name )
{
    return data.filter( (o) => {
        return o.players.find( (player) => {
            return player.name == player_name;
        });
    });
}

let objects = [
    { "_id" : "foo", "players" : [ { "name" : "Jenny"}, { "name" : "Benny"}, { "name" : "Kenny" } ] },
    { "_id" : "bar", "players" : [ { "name" : "Johnny"}, { "name" : "Bunny"}, { "name" : "Kinny" } ] }
];

let found = find_player(objects, "Kinny");

console.log( found[0]._id ); // bar

Upvotes: 0

Related Questions