sql >> データベース >  >> NoSQL >> MongoDB

特定の順序で表示されるドキュメントの配列から2つの要素を検索する

    クエリでこの種の制約が必要な場合は、MongoDBのバージョンがサポートするものに応じて、基本的に2つのオプションがあります。

    MongoDB 3.6

    $ exprを使用することをお勧めします。 「さらに」 有効なドキュメントを実際に選択するための通常のクエリ条件:

    var A = 10, B = 40;
    
    Model.find({
      "subDocs.value": { "$all": [A, B] },
      "$expr": {
        "$lt": [
          { "$arrayElemAt": [
            "$subDocs.index",
            { "$indexOfArray": [ "$subDocs.value", A ]}
          ]},
          { "$arrayElemAt": [
            "$subDocs.index",
            { "$indexOfArray": [ "$subDocs.value", B ]}  
          ]}
        ]
      }
    })
    

    または、「最後の」と一致します 発生:

    Model.find({
      "subDocs.value": { "$all": [A, B] },
      "$expr": {
        "$lt": [
          { "$arrayElemAt": [
            "$subDocs.index",
            { "$subtract": [
              { "$subtract": [{ "$size": "$subDocs.value" }, 1 ] },
              { "$indexOfArray": [ { "$reverseArray": "$subDocs.value" }, A ] }
            ]}
          ]},
          { "$arrayElemAt": [
            "$subDocs.index",
            { "$subtract": [
              { "$subtract": [{ "$size": "$subDocs.value" }, 1 ] },
              { "$indexOfArray": [ { "$reverseArray": "$subDocs.value" }, B ] }
            ]}
          ]}
        ]
      }
    })
    

    以前のバージョン

    同じことですが、ネイティブ演算子がない場合は、<のJavaScript評価を使用する必要があります。 code> $ where

    var A = 10, B = 40;
    
    Model.find({
      "subDocs.value": { "$all": [A, B] },
      "$where": `this.subDocs.find( e => e.value === ${A}).index
          < this.subDocs.find( e => e.value === ${B}).index`
    })
    

    または、「最後の」と一致します 発生:

    Model.find({
      "subDocs.value": { "$all": [10,40] },
      "$where": `let arr = this.subDocs.reverse();
          return arr.find( e => e.value === ${A}).index
            > arr.find( e => e.value === ${B}).index`
    })
    

    集計パイプラインでそれが必要な場合は、を使用します。 $ redact 代わりに、最初の例と同様のロジック:

    var A = 10, B = 40;
    
    Model.aggregate([
      { "$match": { "subDocs.value": { "$all": [A, B] } } },
      { "$redact": {
        "$cond": {
          "if": {
            "$lt": [
              { "$arrayElemAt": [
                "$subDocs.index",
                { "$indexOfArray": [ "$subDocs.value", A ]}
              ]},
              { "$arrayElemAt": [
                "$subDocs.index",
                { "$indexOfArray": [ "$subDocs.value", B ]}  
              ]}
            ]
          },
          "then": "$$KEEP",
          "else": "$$PRUNE"
        }
      }}
    ])
    

    「比較ロジック」は実際には「クエリ演算子式」自体に固有のものではないため、「最適に」ある唯一の部分であると言えば十分です。 インデックスに適用できるのは、 $ all すべての場合のクエリ演算子。残りの重要なロジックは、実際には、主な式が評価された後、および「に加えて」適用され、 $ expr または $ where

    それぞれの基本的なロジックは、基本的に "index"の値を抽出することです。 "value"のそれぞれの値と実際に一致する"first"配列メンバーのプロパティ 財産。これが「未満」の場合、条件は true これにより、返されるドキュメントが満たされます。

    したがって、「計算された評価」はクエリ演算子の効率と一致し、「インデックス」にアクセスできる他のクエリ演算子条件と「組み合わせて」使用されることなく、「フルコレクションスキャン」が開始されることに注意してください。

    ただし、全体的な結果は、一致するすべてのアイテムを最初のクエリ条件に戻し、データベースから戻った「後」にカーソルでそれらを拒否するよりも確かに効率的です。

    $ arrayElemAtのドキュメントも参照してください。 $ indexOfArray $ lt および Array.find() JavaScriptの場合




    1. MongoDBは、シーケンシャル値を生成する方法を提供しますか?

    2. 整数フィールドでのRailsMongoid正規表現

    3. 致命的なエラー:クラス「Mongo」がC:\\ Apache Software Foundation \ Apache2.2 \ htdocs \ sample\testdb.phpに見つかりません

    4. 各ノードのすべての子ノードのサブノードをカウントするには、mongo集約ルックアップに関するガイダンスが必要です