最近、NodejsのMongooseでMongoDBを使い始めました。
$or
条件と_id
フィールドでModel.findメソッドを使用すると、Mongooseが正しく機能しません。
これは動作しません:
User.find({
$or: [
{ '_id': param },
{ 'name': param },
{ 'nickname': param }
]
}, function(err, docs) {
if(!err) res.send(docs);
});
ちなみに、「_ id」部分を削除すると、これは機能します!
User.find({
$or: [
{ 'name': param },
{ 'nickname': param }
]
}, function(err, docs) {
if(!err) res.send(docs);
});
また、MongoDBシェルでは、両方が適切に機能します。
グーグルで解決しました:
var ObjectId = require('mongoose').Types.ObjectId;
var objId = new ObjectId( (param.length < 12) ? "123456789012" : param );
// You should make string 'param' as ObjectId type. To avoid exception,
// the 'param' must consist of more than 12 characters.
User.find( { $or:[ {'_id':objId}, {'name':param}, {'nickname':param} ]},
function(err,docs){
if(!err) res.send(docs);
});
コールバックの代わりにMongooseのクエリビルダー言語とプロミスを使用することを皆にお願いします。
User.find().or([{ name: param }, { nickname: param }])
.then(users => { /*logic here*/ })
.catch(error => { /*error logic here*/ })
Mongoose Queries の詳細をご覧ください。
MongoDBドキュメントによると、「...つまり、MongoDBがインデックスを使用して$ or式を評価するには、$ or式のすべての句がインデックスでサポートされている必要があります。」
したがって、他のフィールドにインデックスを追加すると、機能します。同様の問題があり、これで解決しました。
詳細はこちらをご覧ください: https://docs.mongodb.com/manual/reference/operator/query/or/