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つの要素の配列であり、最初の要素のみを返す必要があります。
現在、_$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];
})
_
上記のオプションの選択は、データサイズとアプリのデザインによって異なります。
3.2以降、 $arrayElemAt
配列の最初の要素を取得します
db.my_collection.aggregate([
{ $project: {
resp : { $arrayElemAt: ['$my_field',0] }
}}
])
$ sliceオペレーターは、このチケットに従って、Mongo 3.1.4の$ project操作で使用できるようにスケジュールされています。 https://jira.mongodb.org/browse/SERVER-6074
これで問題は解消されます。
このバージョンは現在、開発者向けリリースのみであり、まだ安定していません(2015年7月現在)。これは10月/ 11月頃に予想されます。
Mongo 3.1.6以降、
db.my_collection.aggregate([
{
"$project": {
"newArray" : { "$slice" : [ "$oldarray" , 0, 1 ] }
}
}
])
どこ 0
は開始インデックスであり、1
はスライスする要素の数です
開始中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" }