简体   繁体   中英

How can I query mongodb for documents that ids are stored in my `var ids` array with $in?

I want to query all documents that has ids from some array I've passed to my code from user's input:

var attackersIds = fights[i].attackersIds;
attackers = cardsCollection.find({"_id" : { "$oid" : { $in: attackersIds } } });

The problem is I get an error for it:

MongoDB: Can't canonicalize query: BadValue unknown operator: $oid

I have found that it can be solved by using ObjectId(...) but when I do so:

var attackersIds = fights[i].attackersIds;
for(var a=0; a<attackersIds.length; a++){
    attackersIds[a] = ObjectId(attackersIds[a]);
}
attackers = cardsCollection.find({"_id" : { "$oid" : { $in: attackersIds} } });

I get another error:

ReferenceError: \"ObjectId\" is not defined.

I guess it's because of old version of node.js but I cannot change it as my server provider does not allow me to make an upgrade.

So, how can I query mongodb for documents that ids are stored in my var attackersIds array?

The sample documents:

{ "_id": { "$oid": "567ee17ae4b0128ba4ce9049" }, "classId": 9, "name": "Recruit", "description": "", "type": "creature", "cost": { "yellow": 1 }, "attack": 1, "defense": 0, "hp": 1, "area": "field1", "playerId": "56590c7ce4b03fe0cf20842d" }
{ "_id": { "$oid": "567ee17ae4b0128ba4ce904a" }, "classId": 1, "name": "Farm", "description": "", "type": "building", "cost": {}, "attack": 0, "defense": 0, "hp": 5, "generatesMana": { "yellow": 1 }, "area": "hand", "playerId": "56590c7ce4b03fe0cf20842d" }
{ "_id": { "$oid": "567ee17ae4b0128ba4ce904b" }, "classId": 1, "name": "Farm", "description": "", "type": "building", "cost": {}, "attack": 0, "defense": 0, "hp": 5, "generatesMana": { "yellow": 1 }, "area": "hand", "playerId": "56590c7ce4b03fe0cf20842d" }
{ "_id": { "$oid": "567ee17ae4b0128ba4ce904c" }, "classId": 9, "name": "Recruit", "description": "", "type": "creature", "cost": { "yellow": 1 }, "attack": 1, "defense": 0, "hp": 1, "area": "deck", "playerId": "56590c7ce4b03fe0cf20842d" }

Try to swap order of $in and $oid

"_id": {
        "$in": [
            {
                "$oid": "54651022bffebc03098b4567"
            },
            {
                "$oid": "54651022bffebc03098b4568"
            }
        ]
   }

In your case, you would need small helper function, to go from array of id's to array of objects with $oid field

attackers = cardsCollection.find({"_id" : { "$in" : attackersIds.map(function(element){
    return {
        "$oid": element
    });

Try to convert your attackersIds array to array of ObjectId type. How you can do it depends on the package which you use to query mongodb collection.

with mongojs:

var mongojs = require('mongojs');
for(var a=0; a<attackersIds.length; a++){
    attackersIds[a] = mongojs.ObjectId(attackersIds[a]);
}

with mongodb:

ObjectID = require('mongodb').ObjectID;
for(var a=0; a<attackersIds.length; a++){
    attackersIds[a] = new ObjectId(attackersIds[a]);
}

Then try to do query just on _id:

attackers = cardsCollection.find({"_id" : { $in: attackersIds } });

You can try this to cast to an objectid like this:

mongoose.Types.ObjectId(string)

Where mongoose is your mongoose handle:

var mongoose = require('mongoose')

Or you may not need to:

CardsCollection.find({_id:{$in:attackersids}})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM