web-dev-qa-db-ja.com

配列の最初の要素を取得し、Aggregateを使用して返しますか?

Mongo集約を使用して配列の最初の要素を取得して返すにはどうすればよいですか?

私はこのコードを使ってみました:

db.my_collection.aggregate([
    { $project: {
        resp : { my_field: { $slice: 1 } }
    }}
])

しかし、私は次のエラーを受け取ります:

uncaught exception: aggregate failed: {
    "errmsg" : "exception: invalid operator '$slice'",
    "code" : 15999,
    "ok" : 0
}

ご了承ください 'my_field'は4つの要素の配列であり、最初の要素のみを返す必要があります。

17
Alexandre Magro

現在、_$slice_演算子は、集計パイプラインの_$project_操作では使用できません。だからあなたができることは、

最初に_$unwind_、_my_field_配列、次にグループ化して、グループの_$first_要素を取得します。

_db.my_collection.aggregate([
{$unwind:"$my_field"},
{$group:{"_id":"$_id","resp":{$first:"$my_field"}}},
{$project:{"_id":0,"resp":1}}
])
_

または、find()コマンドを使用して、projection部分で$ slice演算子を使用できます。

_db.my_collection.find({},{"my_field":{$slice:1}})
_

pdate:コメントに基づいて、IDがsecondのレコードに対して、配列内のidアイテムのみが必要だとしましょう。

_var field = 2;
var id = ObjectId("...");
_

次に、以下の集約コマンドは、_my_field_、idを含むレコードの__id_配列の2番目の項目を提供します。

_db.my_collection.aggregate([
{$match:{"_id":id}},
{$unwind:"$my_field"},
{$skip:field-1},
{$limit:1}
])
_

上記のロジックは、_$group_の後に_$unwind_演算子が含まれるため、これ以上のレコードには適用できません。 _$group_演算子は、特定のグループのすべてのレコードに対して単一のレコードを生成し、_$limit_または_$skip_演算子を後のステージで適用しても無効になります。

上記のfind()クエリを少し変更すると、期待どおりの結果が得られます。

_db.my_collection.find({},{"my_field":{$slice:[field-1,1]}})
_

これらとは別に、クライアント側でこれを行う方法は常にありますが、レコード数が非常に多い場合は少しコストがかかります。

_var field = 2; 
db.my_collection.find().map(function(doc){
return doc.my_field[field-1];
})
_

上記のオプションの選択は、データサイズとアプリのデザインによって異なります。

7
BatScream

3.2以降、 $arrayElemAt 配列の最初の要素を取得します

db.my_collection.aggregate([
    { $project: {
        resp : { $arrayElemAt: ['$my_field',0] }
    }}
])
16
sidgate

$ sliceオペレーターは、このチケットに従って、Mongo 3.1.4の$ project操作で使用できるようにスケジュールされています。 https://jira.mongodb.org/browse/SERVER-6074

これで問題は解消されます。

このバージョンは現在、開発者向けリリースのみであり、まだ安定していません(2015年7月現在)。これは10月/ 11月頃に予想されます。

1
superluminary

Mongo 3.1.6以降、

db.my_collection.aggregate([
{ 
    "$project": {
        "newArray" : { "$slice" : [ "$oldarray" , 0, 1 ] }
    }
}
])

どこ 0は開始インデックスであり、1はスライスする要素の数です

1
Ali Saeed

開始中Mongo 4.4、集計演算子 $first を使用して、配列の最初の要素にアクセスできます。

// { "my_field": ["A", "B", "C"] }
// { "my_field": ["D"] }
db.my_collection.aggregate([
  { $project: { resp: { $first: "$my_field" } } }
])
// { "resp" : "A" }
// { "resp" : "D" }
0
Xavier Guihot