IndelibleHeff
IndelibleHeff

Reputation: 177

Mongodb like statement with array

I am trying to save some db action by compiling a looped bit of code with a single query, Before I was simply adding to the the like statements using a loop before firing off the query but i cant get the same idea going in Mongo, id appreciate any ideas.... I am basically trying to do a like, but with the value as an array

('app', replaces 'mongodb' down to my CI setup )

Here's how I was doing it pre mongofication:

    foreach ($workids as $workid):
         $this->ci->app->or_like('work',$workid)    ;
    endforeach;
    $query = $this->ci->db->get("who_users");
    $results = $query->result();
    print_r($results);

and this is how I was hoping I could get it to work, but no joy here, that function is only designed to accept strings

    $query = $this->ci->app->like('work',$workids,'.',TRUE,TRUE)->get("who_users");
    print_r($query);

If anyone can think of a way any cunning methods I can get my returned array with a single call again it would be great I've not found any documentation on this sort of query, The only way i can think of is to loop over the query and push it into a new results array.... but that is really gonna hurt if my app scales up.

Upvotes: 1

Views: 2914

Answers (1)

jmikola
jmikola

Reputation: 6922

Are you using codeigniter-mongodb-library? Based on the existing or_like() documentation, it looks like CI wraps each match with % wildcards. The equivalent query in Mongo would be a series of regex matches in an $or clause:

db.who_users.find({
    $or: [
    { work: /.*workIdA.*/ },
    { work: /.*workIdB.*/ },
    ...
]});

Unfortunately, this is going to be quite inefficient unless (1) the work field is indexed and (2) your regexes are anchored with some constant value (e.g. /^workId.*/). This is described in more detail in Mongo's regex documentation.

Based on your comments to the OP, it looks like you're storing multiple ID's in the work field as a comma-delimited string. To take advantage of Mongo's schema, you should model this as an array of strings. Thereafter, when you query on the work field, Mongo will consider all values in the array (documented discussed here).

db.who_users.find({
    work: "workIdA"
});

This query would match a record whose work value was ["workIdA", "workIdB"]. And if we need to search for one of a set of ID's (taking this back to your OR query), we can extend this example with the $in operator:

db.who_users.find({
    work: { $in: ["workIdA", "workIdB", ...] }
});

If that meets your needs, be sure to index the work field as well.

Upvotes: 1

Related Questions