정의되지 않은 데이터 및 쿼리 마이그레이션
이 페이지의 내용
MongoDB 8.0 부터 동등성 매치 표현식에서 null
과의 비교가 undefined
값과 일치하지 않습니다.
예를 예시, 다음과 같은 문서와 쿼리 를 가정해 보겠습니다.
// people collection [ { _id: 1, name: null }, { _id: 2, name: undefined }, { _id: 3, name: [ "Gabriel", undefined ], { _id: 4, names: [ "Alice", "Charu" ] } ]
db.people.find( { name: null } )
MongoDB 8.0 이전에는 위의 쿼리가 다음과 같은 문서와 일치했습니다.
name
필드 는null
(_id: 1
)입니다.name
필드 가undefined
이거나undefined
배열 요소(_id: 2
및_id: 3
)를 포함합니다.name
필드 가 존재하지 않습니다(_id: 4
).
MongoDB 8.0부터 앞의 쿼리 는 name
필드 가 undefined
이거나 undefined
배열 요소가 포함된 문서와 일치하지 않습니다. 쿼리 는 다음과 같은 경우에만 문서와 일치합니다.
name
필드 가null
이거나null
배열 요소(_id: 1
)를 포함합니다.name
필드 가 존재하지 않습니다(_id: 4
).
이 쿼리 동작 변경은 이러한 작업에도 영향을 줍니다.
이 동작 변경을 설명하기 위해 다음을 수행할 수 있습니다.
참고
undefined
더 이상 사용되지 않는 BSON 유형입니다. 최신 버전의 MongoDB Shell 및 드라이버는 삽입 및 업데이트를 수행할 때 undefined
값을 null
로 자동 변환합니다. 이 페이지의 지침 은 이전 운전자 버전 또는 레거시 mongo
셸 의 undefined
값이 있는 배포에 적용됩니다.
정의되지 않은 필드 제거
문서에서 undefined
값이 있는 필드를 유지할 필요가 없는 경우 해당 필드를 제거 할 수 있습니다. MongoDB의 유연한 데이터 모델은 컬렉션의 문서 필드가 일관적인 되지 않아도 되므로 문서의 하위 집합에서 특정 필드 를 제거 할 수 있습니다.
문서에서 정의되지 않은 필드를 제거 하는 방법은 제거 할 필드 이름을 알고 있는지 여부에 따라 달라집니다. 필드 이름을 알고 있으면 인덱스 를 사용할 수 있으므로 작업의 성능이 향상됩니다.
다음 중 하나를 참조하세요.
이름이 알려진 필드 제거
제거 하려는 undefined
값이 포함된 필드 의 이름을 알고 있는 경우 다음 예시 를 사용합니다. 이 예시 에서는 people
컬렉션 을 업데이트하여 다음을 제거.
값이 스칼라 값
undefined
인 경우name
필드 입니다.undefined
name
필드 의 배열 요소.
db.people.updateMany( { name: { $type: "undefined" } }, [ { $set: { "name": { $cond: { // When "name" is an array, convert { name: [ "Alice", undefined ] } // to { name: [ "Alice" ] } if: { $eq: [ { $type: "$name" }, "array" ] }, then: { $filter: { input: "$name", cond: { $not: { $eq: [ { $type: "$$this" }, "undefined" ] } } }, }, // When "name" is scalar undefined, remove it else: "$$REMOVE" } } } } ] )
작업을 실행 하면 people
컬렉션 에 이러한 문서가 포함됩니다.
[ { _id: 1, name: null }, { _id: 2 }, { _id: 3, name: [ "Gabriel" ] } { _id: 4, names: [ "Alice", "Charu" ] } ]
이름을 알 수 없는 필드 제거
어떤 필드에 undefined
값이 포함되어 있는지 모르는 경우 다음 예시 를 사용하여 undefined
최상위 필드를 모두 제거 합니다.
참고
업데이트 필드 이름을 지정하지 않으면 쿼리 에서 인덱스 를 사용할 수 없기 때문에 작업이 수행되지 않습니다. 대규모 컬렉션 에서 다음 예시 를 실행 하는 경우 쿼리 가 느리고 리소스를 많이 사용할 수 있습니다.
다음 예시 에서는 값이 undefined
인 people
컬렉션 에서 최상위 문서 필드를 제거합니다.
db.people.updateMany( { }, [ { $replaceWith: { // Detect undefined top-level fields under the root and remove them $arrayToObject: { $filter: { input: { $objectToArray: "$$ROOT" }, cond: { $not: { $eq: [ { $type: "$$this.v" }, "undefined" ] } } } } } } ] )
작업을 실행 하면 people
컬렉션 에 이러한 문서가 포함됩니다.
[ { _id: 1, name: null }, { _id: 2 }, { _id: 3, name: [ "Gabriel", undefined ] } { _id: 4, names: [ "Alice", "Charu" ] } ]
참고
앞의 접근 방식은 최상위 필드만 수정합니다. 값이 배열 에 표시되기 때문에 _id: 3
이 있는 문서 에는 여전히 undefined
값이 포함되어 있습니다.
정의되지 않은 값을 Null로 업데이트
undefined
데이터 값을 null
데이터 유형 으로 업데이트 할 수 있습니다. 문서 필드를 유지하면서 더 이상 사용되지 않는 undefined
데이터 유형 에서 데이터를 마이그레이션 하려면 이 접근 방식을 사용합니다.
정의되지 않은 필드를 업데이트 하는 방법은 업데이트 할 필드 이름을 알고 있는지 여부에 따라 달라집니다. 필드 이름을 알고 있으면 인덱스 를 사용할 수 있으므로 작업의 성능이 향상됩니다.
다음 중 하나를 참조하세요.
알려진 이름으로 필드 업데이트
null
로 설정하다 하려는 undefined
값이 포함된 필드 의 이름을 알고 있는 경우 다음 예시 를 사용합니다. 이 예시 에서는 people
컬렉션 을 업데이트하여 다음 값을 null
(으)로 설정하다 합니다.
값이 스칼라 값
undefined
인 경우name
필드 입니다.undefined
name
필드 에 표시되는 배열 요소입니다.
db.people.updateMany( { name: { $type: "undefined" } }, [ { $set: { "name": { $cond: { // When "name" is an array, convert { name: [ "Alice", undefined ] } // to { name: [ "Alice", null ] } if: { $eq: [ { $type: "$name" }, "array" ] }, then: { $map: { input: "$name", in: { $cond: { if: { $eq: [ { $type: "$$this" }, "undefined" ] }, then: null, else: "$$this" } } }, }, // When "name" is the scalar undefined, convert to null else: null } } } } ] )
작업을 실행 하면 people
컬렉션 에 이러한 문서가 포함됩니다.
[ { _id: 1, name: null }, { _id: 2, name: null }, { _id: 3, name: [ "Gabriel", null ] } { _id: 4, names: [ "Alice", "Charu" ] } ]
이름을 알 수 없는 필드 업데이트
어떤 필드에 undefined
값이 포함되어 있는지 모르는 경우 다음 예시 를 설정하다 하여 모든 undefined
최상위 필드를 null
로 설정합니다.
참고
업데이트 필드 이름을 지정하지 않으면 쿼리 에서 인덱스 를 사용할 수 없기 때문에 작업이 수행되지 않습니다. 대규모 컬렉션 에서 다음 예시 를 실행 하는 경우 쿼리 가 느리고 리소스를 많이 사용할 수 있습니다.
다음 예시 에서는 people
컬렉션 을 업데이트하여 undefined
최상위 문서 필드를 null
로 설정하다 합니다.
db.people.updateMany( { }, [ { $replaceWith: { // Detect undefined top-level fields under the root and replace them with null $arrayToObject: { $map: { input: { $objectToArray: "$$ROOT" }, in: { $cond: { if: { $eq: [ { $type: "$$this.v" }, "undefined" ] }, then: { k: "$$this.k", v: null }, else: "$$this" } } } } } } ] )
작업을 실행 하면 people
컬렉션 에 이러한 문서가 포함됩니다.
[ { _id: 1, name: null }, { _id: 2, name: null }, { _id: 3, name: [ "Gabriel", undefined ] } { _id: 4, names: [ "Alice", "Charu" ] } ]
참고
앞의 접근 방식은 최상위 필드만 수정합니다. 값이 배열 에 표시되기 때문에 _id: 3
이 있는 문서 에는 여전히 undefined
값이 포함되어 있습니다.
정의되지 않은 값과 일치하도록 쿼리 업데이트
데이터 유형을 null
에서 undefined
마이그레이션 할 수 없는 경우 정의되지 않은 값과 일치하도록 쿼리를 다시 작성할 수 있습니다. 이 접근 방식을 사용하는 경우 데이터에는 더 이상 사용되지 않는 undefined
BSON 유형이 계속 포함됩니다.
null
에 대한 쿼리가 정의되지 않은 값과 일치하도록 하려면 undefined
유형과 명시적으로 일치하는 쿼리 조건자를 추가합니다. 예를 예시, 다음 쿼리 는 name
이 undefined
, null
또는 누락된 문서와 일치합니다.
db.people.find( { $or: [ { name: null }, { name: { $type: "undefined" } } ] } )
쿼리 는 people
컬렉션 의 모든 문서를 반환합니다.
[ { _id: 1, name: null }, { _id: 2, name: undefined }, { _id: 3, name: [ "Gabriel", undefined ], { _id: 4, names: [ "Alice", "Charu" ] } ]