모든 기존 필드를 포함하고 문서에 새 필드 추가


123

기존 필드를 모두 나열하지 않고도 새 필드를 추가하고 모든 기존 필드를 포함하도록 지시 할 수있는 $ 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...
]

이 경우에 사용할 수있는 "모든 필드 포함"키워드와 같은 것이 있습니까? 아니면 모든 필드를 개별적으로 나열하지 않아도되는 다른 방법이 있습니까?


1
이 기능은 다음 주요 릴리스 2.6에서 제공됩니다. 불안정한 개발 브랜치에서 시도해 볼 수 있습니다. "$$ ROOT"를 사용하여 들어오는 문서 전체를 참조하십시오. 이 티켓의 세부 사항을 참조하십시오 jira.mongodb.org/browse/SERVER-5916
하기 Asya Kamsky

1
이 문제는 다른 유용하고 다른 답변과 함께 stackoverflow.com/questions/20497499/… 에서도 발생 합니다.
Vince Bowdren

답변:


168

4.2+에서는 3.4 $set$addFields추가 된 별칭 외에는 아무것도 아닌 집계 파이프 라인 연산자를 사용할 수 있습니다.

$addFields스테이지는 동등 $project명시 입력 문서의 모든 기존의 필드를 지정하고, 새로운 필드를 추가하는 단계.

db.collection.aggregate([
    { "$addFields": { "custom_field": "$obj.obj_field1" } }
])

2
C # 드라이버에서 사용하는 방법을 아십니까? 그것은 존재하지 않는 것 같습니다
호맘

저는 C # 드라이버에 익숙하지 않지만 C # 드라이버 버전$addFields
2.5+에서

나는 C # 드라이버에서이 작업을 수행하는 방법을 찾고 있었으며 지금까지 수행하는 방법은 다음과 같은 것을 사용하는 것 같습니다.IAggregateFluent<TResult>.AppendStage(new JsonPipelineStageDefinition<TInput, TOutput>("{ $addFields : { myField: 'myValue' }}")
sboisse

4
난 당신이 같은 필드 이름을 지정하는 경우에도 필드를 대체 할 수 있다는 것을 발견
CME64

79

$$ ROOT 를 사용하여 루트 문서를 참조 할 수 있습니다 . 이 문서의 모든 필드를 필드에 유지하고 그 후에 가져 오십시오 (클라이언트 시스템에 따라 다름 : Java, C ++, ...).

 [
    {
        $project: {
            custom_field: "$obj.obj_field1",
            document: "$$ROOT"

        }
    },
    ... //group, match, and whatever...
]

17
그러나 이것은라는 포함 된 문서 생성합니다 document생성 된 하나의 옵션이 문서가 있었을 것이다 좋네요 병합 ...
알렉산더 Suraphel

2
포함 된 문서를 만들지 않고 모든 키 값 쌍을 통과하는 솔루션을 아는 사람이 있습니까?
ugotchi

11
숨을 참아. MongoDB 3.4에는이를 수행하는 $ addFields 집계 단계 가 함께 제공됩니다 . stackoverflow.com/a/24557029/4653485를 참조하십시오 .
Jérôme

이것은 (적어도 JS에서는) 스프레드 연산자를 사용하여 새로 custom_field첨부 된 원본 개체를 다시 빌드 할 수 있으므로 현재 최상의 솔루션 인 것 같습니다 . const newObj = { ...result.document, custom_field: result.custom_field }
ffritz

7

>>>이 경우 또는 다른 솔루션에서 사용할 수있는 "모든 필드 포함"키워드와 같은 것이 있습니까?

불행히도 집계 작업에 "모든 필드를 포함"하는 연산자가 없습니다. 유일한 이유는 집계가 대부분 컬렉션 필드 (sum, avg 등)에서 데이터를 그룹화 / 계산하고 모든 컬렉션 필드를 반환하기 위해 생성되기 때문에 직접적인 목적이 아닙니다.


... 집계는 대부분 컬렉션 필드에서 데이터를 그룹화 / 계산하기 위해 생성되기 때문에 ... 사실 최고의 답변입니다!
felipsmartins

1
posts_id, title, body, likes 필드 가있는 컬렉션 이 있습니다. likes 필드는 게시물을 좋아하는 사용자 _id의 배열입니다. 모든 _id, title, body, likeCount가있는 모든 게시물을 어떻게 나열 할 수 있습니까? 이 경우 모든 필드를 반환하는 것이 직접적인 목적입니다.
doc_id

3

버전 2.6.4부터 Mongo DB에는 $project집계 파이프 라인에 대한 이러한 기능이 없습니다 . 로부터 문서 에 대한 $project:

지정된 필드 만있는 문서를 파이프 라인의 다음 단계로 전달합니다. 지정된 필드는 입력 문서의 기존 필드 또는 새로 계산 된 필드 일 수 있습니다.

_id 필드는 기본적으로 출력 문서에 포함됩니다. 입력 문서의 다른 필드를 출력 문서에 포함하려면 $ project에 포함을 명시 적으로 지정해야합니다.


2

문서에 새 필드를 추가하려면 다음을 사용할 수 있습니다. $addFields

문서에서

문서의 모든 필드에 다음을 사용할 수 있습니다. $$ROOT

db.collection.aggregate([

{ "$addFields": { "custom_field": "$obj.obj_field1" } },
{ "$group": {
        _id : "$field1",
        data: { $push : "$$ROOT" }
    }}
])

0

@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);
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.