2

次のようなドキュメントを含む MonogDB コレクションがあるとします。

{name: 'Some Name', components: {ARRAY OF ITEMS}}

コンポーネント内のアイテムの名前と数を返すにはどうすればよいですか? map/reduce を使用する必要がありますか?

PHP の Mongo 拡張機能を使用しています。

編集:PHPの現在のコードのスニペット(動作中)ですが、コンポーネントの数が欲しいだけです

$fields = array(
    'name', 'components'
);
$cursor = $this->collection->find(array(), $fields);
$cursor->sort(array('created_ts' => -1));

if (empty($cursor) == true) {
    return array();
} else {
    return iterator_to_array($cursor);
}

ありがとう、ジム

4

4 に答える 4

1

map-reduce を使用するか、次のように単純なグループクエリを使用できます。name プロパティは一意のキーであると想定しているため、通常は group 関数を使用する理由ではありませんが、これは機能するはずです。

db.test.group({
 key: { name:true },
 reduce: function(obj,prev) {
  var count = 0;
  for(k in obj.components)
   count++;
  prev.count = count;
 },
 initial: { count: 0}
});

コンポーネントの配列があるとおっしゃいましたが、コンポーネントを配列では{}なくオブジェクトとして保存しているようです[]。コンポーネント オブジェクトのすべてのプロパティをカウントするために、reduce 関数にループを追加する必要があったのはそのためです。実際に配列である場合は、単に.lengthプロパティを使用できます。

PHPでは、次のようになります(マニュアルから):

$keys = array('name' => 1);
$initial = array('count' => 0);
$reduce =<<<JS
function(obj,prev) {
  var count = 0;
  for(k in obj.components)
   count++;
  prev.count = count;
 },
JS;

$m = new Mongo();
$db = $m->selectDB('Database');
$coll = $db->selectCollection('Collection');
$data = $coll->group($keys, $initial, $reduce);

最後に、コンポーネントの数に定期的にアクセスしようとしている場合は、その数をドキュメントの追加プロパティとして保存し、変更があるたびに更新することを強くお勧めします。このカウントに基づいてフィルタリングするクエリを作成しようとしている場合は、そのコンポーネント プロパティにインデックスを追加することもできます。

于 2011-09-14T16:35:06.247 に答える
0

ジム-

これらは2つの別々の操作です。得られた結果に対するPHPのカウントを活用したい場合を除いて、次のようなことを行います。

$m = new Mongo();
$db = $m->selectDB('yourDB');
$collection = $db->selectCollection('MyCollection');
$cursor = $collection->find(array(), array("name"=>1, "components"=>1));
foreach($cursor as $key){
   echo($key['name'].' components: '.count($key['components']);
}
于 2011-09-13T13:16:18.223 に答える
0

db.eval()を使用して、JavaScript で計算を記述できます。

于 2011-09-13T13:29:30.480 に答える
0

今日、これに出くわしました。集計で新しいドライバーを使用している場合は、php でこれを行うことができます (このスキーマを指定)

   {name: 'Some Name', components: {ARRAY OF ITEMS}}

PHP の場合:

   $collection = (new Client())->db->my_collection;
   $collection->aggregate([
       '$match' => ['name' => 'Some Name'],
       '$group' => [
             '_id' => null,
             'total'=> ['$sum' => "\$components"]
        ]
  ]);

ここでのPHPの秘訣は、$ドル記号をエスケープすることです。これは、基本的に、サイズまたは合計を使用するときにmongoのドキュメントに記載されていることです

https://docs.mongodb.com/manual/reference/operator/aggregation/size/

https://docs.mongodb.com/manual/reference/operator/aggregation/sum/

私が抱えていた問題は、mongo がフィールドを as に入れる"$field"ことであり、PHP は、変数補間を行う方法のために、それをまったく好きではありません。ただし、 をエスケープする$と、正常に動作します。

この特定のケースでは、似たようなことをする必要があると思いますが、$project代わりに$groupLike this

   $collection = (new Client())->db->my_collection;
   $collection->aggregate([
       '$match' => ['name' => 'Some Name'],
       '$project' => [
            'name' => "\$name",
            'total'=> ['$sum' => "\$components"]
        ]
   ]);

これは古い質問ですが、答えが選択されていないので、ここに残します。

于 2016-08-31T21:00:44.573 に答える