기존 필드를 모두 나열하지 않고도 새 필드를 추가하고 모든 기존 필드를 포함하도록 지시 할 수있는 $ project 집계 단계를 정의하고 싶습니다.
내 문서는 다음과 같이 많은 필드가 있습니다.
{
obj: {
obj_field1: "hi",
obj_field2: "hi2"
},
field1: "a",
field2: "b",
...
field26: "z"
}
다음과 같은 집계 작업을 만들고 싶습니다.
[
{
$project: {
custom_field: "$obj.obj_field1",
//the next part is that I don't want to do
field1: 1,
field2: 1,
...
field26: 1
}
},
... //group, match, and whatever...
]
이 경우에 사용할 수있는 “모든 필드 포함”키워드와 같은 것이 있습니까? 아니면 모든 필드를 개별적으로 나열하지 않아도되는 다른 방법이 있습니까?
답변
4.2+에서는 3.4 $set
에 $addFields
추가 된 별칭 외에는 아무것도 아닌 집계 파이프 라인 연산자를 사용할 수 있습니다.
$addFields
스테이지는 동등$project
명시 입력 문서의 모든 기존의 필드를 지정하고, 새로운 필드를 추가하는 단계.
db.collection.aggregate([
{ "$addFields": { "custom_field": "$obj.obj_field1" } }
])
답변
$$ ROOT 를 사용하여 루트 문서를 참조 할 수 있습니다 . 이 문서의 모든 필드를 필드에 유지하고 그 후에 가져 오십시오 (클라이언트 시스템에 따라 다름 : Java, C ++, …).
[
{
$project: {
custom_field: "$obj.obj_field1",
document: "$$ROOT"
}
},
... //group, match, and whatever...
]
답변
>>>이 경우 또는 다른 솔루션에서 사용할 수있는 “모든 필드 포함”키워드와 같은 것이 있습니까?
불행히도 집계 작업에 “모든 필드를 포함”하는 연산자가 없습니다. 유일한 이유는 집계가 대부분 컬렉션 필드 (sum, avg 등)에서 데이터를 그룹화 / 계산하고 모든 컬렉션 필드를 반환하기 위해 생성되기 때문에 직접적인 목적이 아닙니다.
답변
버전 2.6.4부터 Mongo DB에는 $project
집계 파이프 라인에 대한 이러한 기능이 없습니다 . 로부터 문서 에 대한 $project
:
지정된 필드 만있는 문서를 파이프 라인의 다음 단계로 전달합니다. 지정된 필드는 입력 문서의 기존 필드 또는 새로 계산 된 필드 일 수 있습니다.
과
_id 필드는 기본적으로 출력 문서에 포함됩니다. 입력 문서의 다른 필드를 출력 문서에 포함하려면 $ project에 포함을 명시 적으로 지정해야합니다.
답변
문서에 새 필드를 추가하려면 다음을 사용할 수 있습니다. $addFields
문서의 모든 필드에 다음을 사용할 수 있습니다. $$ROOT
db.collection.aggregate([
{ "$addFields": { "custom_field": "$obj.obj_field1" } },
{ "$group": {
_id : "$field1",
data: { $push : "$$ROOT" }
}}
])
답변
@Deka 회신에 따르면 c # mongodb 드라이버 2.5의 경우 아래와 같은 모든 키로 그룹화 된 문서를 얻을 수 있습니다.
var group = new BsonDocument
{
{ "_id", "$groupField" },
{ "_document", new BsonDocument { { "$first", "$$ROOT" } } }
};
ProjectionDefinition<BsonDocument> projection = new BsonDocument{{ "document", "$_document"}};
var result = await col.Aggregate().Group(group).Project(projection).ToListAsync();
// For demo first record
var fistItemAsT = BsonSerializer.Deserialize<T>(result.ToArray()[0]["document"].AsBsonDocument);