41

usersコレクション内の MongoDB ドキュメントを考えてみましょう。

{ username : 'Alex', tags: ['C#', 'Java', 'C++'] }

tagsサーバー側から (タグをクライアントに渡さずに) 配列の長さを取得する方法はありますか?

ありがとうございました!

4

6 に答える 6

31

ユーザー名 Alex が一意の場合、次のコードを使用できます。

db.test.insert({username:"Alex", tags: ['C#', 'Java', 'C++'] });
db.test.aggregate(
  {$match: {username : "Alex"}}, 
  {$unwind: "$tags"},
  {$project: {count:{$add:1}}},
  {$group: {_id: null, number: {$sum: "$count" }}}
);
{ "result" : [ { "_id" : null, "number" : 3 } ], "ok" : 1 }
于 2012-12-15T21:24:24.577 に答える
19

MongoDB (2.6 リリース)は集計での操作をサポートするようになりました。 $size

ドキュメントから:

{ <field>: { $size: <array> } }

これを使用して、次のいずれかで目的を達成できます。

db.users.aggregate(
   [
      {
         $group: {
            _id: "$username",
            tags_count:  {$first: {$size: "$tags" }}
         }
      }
   ]
)

また

db.users.aggregate(
   [
      {
         $project: {
            tags_count: {$size: "$tags"}
         }
      }
   ]
)
于 2014-04-08T14:38:16.043 に答える
16

$ incを使用して、またはスケジュールに従ってジョブを介して、各保存のタグの数を(個別のフィールドとして)計算する方が効率的かもしれないと思います。

map / reduce(正規の例)を使用してこれを行うこともできますが、それはあなたが望むものではないようです。

あなたが求めていることを正確に行うことができるかどうかはわかりませんが、特定のサイズに一致するすべてのドキュメントを$sizeでクエリできます...

> db.collection.find({ tags : { $size: 3 }});

これで、3つのタグが付いたすべてのドキュメントが取得されます...

于 2011-07-17T09:34:02.510 に答える
9

現在、それを行う唯一の方法はを使用しているようですdb.evalが、これは他の操作のためにデータベースをロックします

最も速度効率の良い方法は、配列の長さを格納するフィールドを追加し、$incおよび$push操作によってそれを維持することです。

于 2011-07-17T09:31:47.200 に答える
0

配列サイズを照会し、それが 0 より大きいが 1 ~ 3 のいずれかである可能性がある場合に返す必要があるため、小さな回避策を実行しました。

これが私の解決策でした:

db.test.find($or : [{$field : { $exists : true, $size : 1}},
                    {$field : { $exists : true, $size : 2}},
                    {$field : { $exists : true, $size : 3}}, ])

これは基本的に、属性が存在し、サイズが 1、2、または 3 の場合にドキュメントを返します。特定のサイズまたは範囲内を探している場合、ユーザーはさらにステートメントを追加してインクリメントできます。完璧ではないことはわかっていますが、うまく機能し、比較的迅速でした. 属性に 1 ~ 3 個のサイズしかなかったので、このソリューションは機能しました。

于 2014-11-06T16:01:43.520 に答える