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

mongodbクエリ:$gtを含む$sizeは常に0を返します

    <のドキュメントで実際に参照されているように、これを行うことはできません。 code> $ size 。そのため、オペレーターだけが「リテラル」の結果を評価し、できない 求めているような「範囲演算子」と組み合わせて使用​​してください。

    唯一の実際のオプションは、 $ not オペレーター。これは完全に有効です:

    db.userStats.count({ "sessions": { "$not": { "$size": 0 } } });
    

    または、 $sizeの他の化身でテストします 集約フレームワークでは、MongoDBのバージョンが2.6以上である限り:

    db.userStats.aggregate([
        { "$group": {
             "_id": null,
             "count": {
                 "$sum": {
                     "$cond": [
                         { "$gt": [ { "$size": "$sessions", 0 } ] },
                         1,
                         0
                     ]
                 }
             }
        }}
    ])
    

    おそらく、 $ where JavaScript評価の形式:

    db.userStats.count(function() { return this.sessions.length > 0 });
    

    ただし、前回のバージョンよりも遅い可能性があります。

    または、実際には、"ドット表記"<を使用してこれを行うことができます。 / a> 、および $ examples 演算子:

    db.userStats.count({ "sesssions.0": { "$exists": true } });
    

    一般的な考え方として、インデックス 0に要素がある場合 その場合、配列にはある程度の長さがあります。

    それはすべてあなたのアプローチに依存しますが、これらのフォームのどれでも正しい結果が得られます。

    ただし、MongoDBの「最高の」パフォーマンスを得るには、いずれも使用しないでください。 これらのメソッドの。代わりに、配列の「長さ」を検査するドキュメントのプロパティとして保持してください。これを「インデックス付け」することができ、発行されたクエリは実際にそのインデックスにアクセスできますが、上記のいずれもできません。

    このように維持します:

    db.userStats.update(
         { "_id": docId, "sessions": { "$ne": newItem } },
         {
             "$push": { "sessions": newItem },
             "$inc": { "countSessions": 1 }
         }
    )
    

    または削除するには:

    db.userStats.update(
         { "_id": docId, "sessions": newItem  },
         {
             "$pull": { "sessions": newItem },
             "$inc": { "countSessions": -1 }
         }
    )
    

    次に、「countSesssions」でクエリを実行できます。これにより、最高のパフォーマンスを得ることができます。

    db.userStats.find({ "countSessions": { "$gt": 0 } })
    

    そして、それがそれを行うための「最良の」方法です。



    1. NoSQL-MongoDBとCouchDB

    2. C#BsonArrayを使用したMongoDBコレクションのInsertManyドキュメント

    3. (リレーショナルテーブルの代わりに)MongoDBでの多対多の関係の設計

    4. Node.jsでfindOneをループで使用するには時間がかかりすぎる