2017-07-12 24 views
2

複数のORを持つNodeを使ってMongoクエリを動的に構築したいと考えています。この問合せのポイントは、複数の検索語を使用してデータベース内でAND検索を行うことです。MongoDB Queryを複数のORで動的に構築する方法は?

たとえば、「dog」と「cereal」という単語を含むレコードを検索したいとします。クエリでは、レコードのどこかに "dog"と "cereal"を持つレコードのみが返されます(つまり、検索クエリが異なる列に表示される可能性があります)。私は、クエリは、このように見える終わる必要があることを知っている

query = { 
    $and: [ 
     {$or: [ 
      {col1: {$regex: "first", $options: "i"}}, 
      {col2: {$regex: "first", $options: "i"}} 
     ]}, 
     {$or: [ 
      {col1: {$regex: "second", $options: "i"}}, 
      {col2: {$regex: "second", $options: "i"}} 
     ]} 
    ] 
} 

マイノードコードは、しかし、これを生成しません。 これは私がこれを考え出すに得ている最も近い:

var regexQueryWrapper = {}; 
regexQueryWrapper["$and"] = []; 
var wrapper = {}; 
wrapper["$or"] = []; 
var query = {}; 
searchTerms.forEach(function(term) { 
    searchFields.forEach(function(field) { 
     query[field] = {$regex: term, $options: 'i'}; 
     wrapper["$or"].push(query); 
    }); 
    regexQueryWrapper["$and"].push(wrapper); 
}); 

これを行うための最善の方法は何ですか?私が紛失している別のアプローチがありますか?

+0

あなたはMongoDBの者を使用して見てきました[テキスト検索](https://docs.mongodb.com/manual/text-search/)これは?あなたのユースケースは良いフィット感があります。 – JohnnyHK

+0

@JohnnyHK私は持っていて、私はそれを使いたいです。しかし、それはアプリケーションの要件である検索のようなものではありません。 – sumowrestler

答えて

1

閉じる。あなたはオブジェクトを再利用しているようです。一時オブジェクトは、それぞれのforeach反復で再初期化してここにあなたが探しているクエリを構築し、いくつかの調整後のコードは、です:

var regexQueryWrapper = {}; 
regexQueryWrapper["$and"] = []; 

searchTerms.forEach(function(term) { 

    var wrapper = {"$or": []}; 

    searchFields.forEach(function(field) { 
     var query = {}; 
     query[field] = {$regex: term, $options: 'i'}; 
     wrapper["$or"].push(query); 
    }); 

    regexQueryWrapper["$and"].push(wrapper); 

}); 

そしてmapを使用して代替実装:

var query = {"$and": searchTerms.map(function(term) { 

    return {"$or": searchFields.map(function(field) { 

     var o = {}; 
     o[field] = {"$regex": term, "$options": "i"}; 
     return o; 

    })}; 

})}; 
1

これを複雑にすると思います。

ほとんど2つのネストされた配列(andおよびor)を操作しているという事実を考えて、段階的にクエリを作成します。

query = {and: []}; 

function add_and(or_query) { 
query["and"].push({or: or_query}); 
} 

function build_or_query(term) { 
return [ 
    {col1 : {$regex: term, $options: "i"}}, 
    {col2: {$regex: term, $options: "i"}} 
] 
} 

名前の変更や、ユーザー入力イベントを管理するために、あなたのコードに合うようにこれらの機能を使用します。配列や配列を返す別の1をプッシュ機能付

、NodeJSコードは次のようになります。 (二つの機能)などの

function add_and(term) { 
query["and"].push({or: [ 
    {col1 : {$regex: term, $options: "i"}}, 
    {col2: {$regex: term, $options: "i"}} 
]}); 
} 

用途:

add_and(build_or_query('test1')); 
add_and(build_or_query('test2')); 

など

(一の機能):

add_and('test1'); 
add_and('test2'); 

あなたがしたい場合は、非常にコンパクトなコードを確保し、それらをマージすることができます結果:

{ 
    and: [ 
    { or: [ { col1: { '$regex': 'test1', '$options': 'i' } }, 
      { col2: { '$regex': 'test1', '$options': 'i' } } ] }, 
    { or: [ { col1: { '$regex': 'test2', '$options': 'i' } }, 
      { col2: { '$regex': 'test2', '$options': 'i' } } ] } 
    ] 
} 
+0

私は[このウェブサイト](http://www.webtoolkitonline.com/javascript-tester.html)であなたのソリューションを試したとき、私はそれが無効なjavascriptだと言われました。すべてが私にとって正しいように見えるので変です... – sumowrestler

+0

私はNodeJSで私のソリューションを試してみました。 – Fabien

+0

PS:あなたのサイトで試したところ、 "build_or_query("最短の解決方法をウェブサイトでテストすると削除されました。 – Fabien

関連する問題