$ or条件付きのMongooseのfindメソッドが正しく機能しない


116

最近、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シェルでは、どちらも正しく動作します。

回答:


211

私はグーグルでそれを解決しました:

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);
});

2
このソリューションが単語で機能する理由を説明できますか?ありがとう
Alexander Mills

これは、かなり具体的な問題の解決策のように見えます。検索を続ける必要があるかもしれません。
Kesarion

あなたの参照を提供できますか?この場合、なぜparamは12文字を超える必要があるのですか?これはあなたの問題またはObjectId()の要件に固有のものですか?パラメータに12文字がない場合はどうなりますか?ありがとう!
yusong

6
あなたはまた、次のようにObjectIdがチェックすることができますconst mongoose = require('mongoose'); mongoose.Types.ObjectId.isValid(objectidtocheck)
オルハン

@yusongこれはmongooseによるもので、有効なObjectIdでない場合はエラーがスローされます。私の前に述べた、よりクリーンな方法。
Haydar Ali Ismail

53

コールバックの代わりにMongooseのクエリビルダー言語とpromiseを使用するようにみんなに要請します。

User.find().or([{ name: param }, { nickname: param }])
    .then(users => { /*logic here*/ })
    .catch(error => { /*error logic here*/ })

マングースクエリの詳細については、こちらをご覧ください。


大好きです!ヘッドアップをありがとう!
zeckdude

0

mongoDBのドキュメントによれば、「...つまり、MongoDBがインデックスを使用して$ or式を評価するには、$ or式のすべての句がインデックスでサポートされている必要があります。」

したがって、他のフィールドにインデックスを追加すれば機能します。同様の問題があり、これで解決しました。

詳しくはこちらをご覧くださいhttps : //docs.mongodb.com/manual/reference/operator/query/or/


1
これは間違ったステートメントです-インデックスを使用する必要がある場合にのみインデックスが必要です。つまり、パフォーマンスのために、コレクションスキャンを回避するためです。パフォーマンスが問題でない場合でも、それは問題ではない...(例えば、コレクションは非常に小さい)
アンディ・ロレンツ

0
async() => {
let body = await model.find().or([
  { name: 'something'},
  { nickname: 'somethang'}
]).exec();
console.log(body);
}
/* Gives an array of the searched query!
returns [] if not found */

1
あなたの答えは、ゴビンド・ライの答えとどう違うのですか?あなたのものを彼らのものより優れているものは何ですか?
BDL

async / await、優れたものは何ですか?
Firez

2
このサイトでは、コードのみの回答は一般的に嫌われています。回答を編集して、コードのコメントや説明を含めていただけませんか?説明では、次のような質問に答える必要があります。どうやってやるの?どこに行くの?OPの問題をどのように解決しますか?参照:アンサーの方法。ありがとう!
Eduardo Baitello
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.