11

私は非常に単純だと思うことをやろうとしています。共通キーと可変数の属性を持つ一連のレコードがmongoにあるとします。すべての属性を選択し、レコード全体で名前でグループ化したいと考えています。例えば

{ Name: George, x: 5, y: 3 }
{ Name: George, z: 9 }
{ Name: Rob, x: 12, y: 2 }

次のような CSV を作成したいと思います。

Name     X   Y   Z
George   5   3   9
Rob      12  2

試した

DB.data.aggregate({ $group : { _id : "$Name" } })

残念ながら、すべての名前をレコードとして返しますが、可能なすべての属性の結合ではありません。

4

4 に答える 4

11

属性を結合したい場合は、それらを に追加する必要がありますgroup。たとえば、$addToSet各名前でグループ化された x、y、z 属性の一意の値を見つけるために使用します。

db.data.aggregate(
    { $group : {
            _id : "$Name",
            x: { $addToSet: "$x" },
            y: { $addToSet: "$y" },
            z: { $addToSet: "$z" },
    }}
)

戻り値:

{
    "result" : [
        {
            "_id" : "Rob",
            "x" : [
                12
            ],
            "y" : [
                2
            ],
            "z" : [ ]
        },
        {
            "_id" : "George",
            "x" : [
                5
            ],
            "y" : [
                3
            ],
            "z" : [
                9
            ]
        }
    ],
    "ok" : 1
}
于 2012-08-31T05:01:00.090 に答える
0

Stennie のソリューションでは、クエリしているコレクション内の一致する各アイテムからどの属性を返したいかを正確に知る必要があります。これは必ずしもそうではありません。

この問題は、作成中の Groovy on Grails アプリケーション内で解決する必要がありました。

「X による検索」リクエストを処理するために、次のようなメソッドを作成しました。

private List<DBObject> findDistinctPages(Map by) {
    def command =
        new GroupCommand(
                (DBCollection) db.pages,
                new BasicDBObject(['url': 1]),
                new BasicDBObject(by),
                new BasicDBObject([:]),
                'function ( current, result ) { for(i in current) { result[i] = current[i] } }',
                ''
        )
    db.pages.group(command).sort { it.title }
}

そして、次のようにコード内で呼び出します。

def pages = findDistinctPages([$or: [[type: 'channel'], [type: 'main']]])

これは、最初のクエリの結果を GroupCommand の最後にある JavaScript 関数に渡すことによって機能します。Mongo は、最初のクエリで指定した属性のみを返します。そのため、結果を 2 回繰り返し、mongo からの残りのデータを入力する必要があります。

于 2013-10-18T15:06:55.087 に答える
0

これを行う別の方法は次のとおりです。

$connection = 'mongodb://localhost:27017';
$con        = new Mongo($connection); // mongo connection

$db         = $con->test; /// database
$collection = $db->prb; // table

$keys       = array("Name" => 1,"x"=>1,"y"=>1,"z"=>1);

// set intial values
$initial    = array("count" => 0);

// JavaScript function to perform
$reduce     = "function (obj, prev) { prev.count++; }";

$g          = $collection->group($keys, $initial, $reduce);

echo "<pre>";
print_r($g);

次のような答えが得られます (正確な出力ではありません)。

Array
(
    [retval] => Array
        (
            [0] => Array
                (
                    [Name] => George
                    [x] => 
                    [y] =>
                    [z] =>
                    [count] => 2
                )

            [1] => Array
                (
                    [Name] => Rob
                    [x] => 
                    [y] =>
                    [z] =>
                    [count] => 1
                )

        )

    [count] => 5
    [keys] => 3
    [ok] => 1
)
于 2013-02-11T05:32:39.467 に答える
-1

グループに使用$addToSetすると、うまくいきます

db.data.aggregate(
    { $group : {
            _id : "$Name",
            x: { $addToSet: "$x" },
            y: { $addToSet: "$y" },
            z: { $addToSet: "$z" },
    }}
)
于 2013-06-19T05:53:44.547 に答える