쿼리 플래너
새로운 Amazon DocumentDB용 쿼리 플래너(플래너 버전 2.0)는 고급 쿼리 최적화 기능과 향상된 성능을 제공합니다. Amazon DocumentDB 5.0용 플래너 버전 2.0은 인덱스와 함께 find 및 update 연산자를 사용할 때 이전 버전보다 최대 10배 향상된 성능을 제공합니다. 성능 개선은 주로 보다 최적화된 인덱스 계획 사용 및 부정 연산자($neq, $nin), 중첩 $elementMatch와 같은 연산자에 대한 인덱스 스캔 지원 활성화에서 비롯됩니다. 플래너 버전 2.0 쿼리는 개선된 비용 추정 기법, 최적화된 알고리즘 및 향상된 안정성을 통해 더 빠르게 실행됩니다. 플래너 버전 2.0은 계획 캐시 필터 API도 지원하므로 플래너 안정성이 향상됩니다. 이 기능을 통해 Amazon DocumentDB 5.0은 이제 다양한 버전의 쿼리 플래너 중에서 선택할 수 있는 기능을 제공합니다.
사전 조건
플래너 버전 2.0에는 다음 사전 조건이 적용됩니다.
플래너 버전 2.0은 엔진 버전 5.0을 사용할 수 있는 모든 리전에서 제공됩니다.
버전 2.0을 기본 쿼리 플래너로 사용하도록 선택하려면 클러스터가 Amazon DocumentDB 버전 5.0의 엔진 패치 버전 3.0.15902 이상에 있어야 합니다. 최신 엔진 버전 패치로 업데이트하는 단계는 클러스터의 엔진 버전에 대한 패치 업데이트 수행 섹션을 참조하세요.
플래너 버전 2.0을 기본 쿼리 플래너로 설정하려면 클러스터 파라미터 그룹을 업데이트할 수 있는 IAM 권한이 필요합니다.
플래너 버전 2.0을 기본 쿼리 플래너로 선택
다음 단계에 따라 콘솔 또는 CLI에서 2.0을 기본 쿼리 플래너로 선택합니다.
Amazon DocumentDB 클러스터 파라미터 수정의 단계에 따라 클러스터의 파라미터 그룹을 수정합니다.
'plannerVersion'이라는 파라미터의 경우 값을 플래너 버전을 나타내는 2.0으로 변경합니다.
즉시 적용을 선택합니다(재부팅 시 적용을 선택하는 경우 다음에 클러스터를 재부팅할 때까지 선택이 적용되지 않음).
모범 사례
예상 결과를 얻으려면 플래너 버전 2.0을 적용할 때 다음 모범 사례를 사용하세요.
글로벌 클러스터에서 두 리전의 클러스터 파라미터 그룹에서 동일한 plannerVersion 값(1.0 또는 2.0)을 선택합니다. 기본 리전 및 보조 리전에서 다른 플래너 버전을 선택하면 쿼리 동작과 성능이 일관되지 않을 수 있습니다.
예약된 유지 관리 기간 동안 또는 감소된 트래픽 기간 동안 플래너 버전 2.0으로 업데이트하면 워크로드가 활발하게 실행 중일 때 플래너 버전이 변경되는 경우 오류율이 증가할 수 있으므로 중단이 가장 적습니다.
플래너 버전 2.0은 MongoDB 쉘 버전 5.0에서 가장 최적으로 작동합니다.
제한 사항
플래너 버전 2.0에는 다음과 같은 제한이 적용됩니다.
플래너 버전 2.0은 탄력적 클러스터에서 지원되지 않으며, 플래너 버전 1.0으로 대체됩니다.
플래너 버전 2.0은 집계 및 고유 명령에 대해 지원되지 않으며, 플래너 버전 1.0으로 대체됩니다.
정규식, 텍스트 검색, 지리 공간, json 스키마 또는 필터의 $expr이 포함된 쿼리는 플래너 버전 2.0의 계획 캐시 필터에서 지원되지 않습니다.
Find 및 Update 연산자에 대한 개선 사항
플래너 버전 2.0은 find, update, delete, find-and-modify 명령을 포함한 기본 작업을 최적화합니다. 다음의 탭 섹션에서는 인덱스에 대한 향상된 기능과 플래너 버전 2.0의 쿼리 성능 개선을 보여줍니다.
- Enhanced index support
-
플래너 버전 2.0에는 $nin, $ne, $not {eq}, $not {in} 및 $type, $elemMatch를 포함한 부정 연산자에 대한 인덱스 지원이 추가되었습니다.
Sample Document: { "x": 10, "y": [1, 2, 3] }
db.foo.createIndex({ "x": 1, "y": 1 })
db.foo.find({ "x": {$nin: [20, 30] }})
db.foo.find({"x":{ $type: "string" }})
db.foo.createIndex({"x.y": 1})
db.foo.find({"x":{$elemMatch:{"y":{$elemMatch:{"$gt": 3 }}}}})
플래너 버전 2.0은 $exists가 쿼리 표현식에 없는 경우에도 희소 인덱스 또는 부분 인덱스를 사용합니다.
Sample Document: {"name": "Bob", "email": "example@fake.com" }
Using Planner Version 1.0, you can specify the command as shown below:
db.foo.find({email: "example@fake.com", email: {$exists: true}})
Using Planner Version 2.0, you can specify command without $exists:
db.foo.find({ email: "example@fake.com" })
플래너 버전 2.0은 쿼리 조건이 부분 인덱스 필터 표현식과 정확히 일치하지 않는 경우에도 부분 인덱스를 활용합니다.
Sample Document: {"name": "Bob", "age": 34}
db.foo.createIndex({"age":1},{partialFilterExpression:{"age":{$lt:50}}})
With Planner Version 1.0, index is used only when the query condition meets the partial
index filter criterion:
db.foo.find({"age":{$lt:50}})
With Planner Version 2.0, index is used even when the query condition doesn’t meet the index
criterion:
db.foo.find({"age":{$lt:30}})
플래너 버전 2.0은 $elemMatch 쿼리와 함께 부분 인덱스 스캔을 활용합니다.
Sample Document: {"name": "Bob", "age": [34,35,36]}
db.foo.createIndex({"age":1},{partialFilterExpression:{"age":{$lt:50,$gt:20}}})
db.foo.find({age:{$elemMatch:{$lt:50,$gt:20}}})
플래너 버전 2.0에는 애플리케이션 코드에 $hint를 제공할 필요 없이 $regex에 대한 인덱스 스캔 지원이 포함되어 있습니다. $regex는 접두사 검색에서만 인덱스를 지원합니다.
Sample Document: { "x": [1, 2, 3], "y": "apple" }
db.foo.createIndex({ "x": 1, "y": 1 })
db.foo.find({"y":{ $regex: "^a" }})
플래너 버전 2.0은 다중 키 필드에 대한 등식 조건을 사용하여 다중 키 인덱스와 관련된 쿼리의 성능을 개선합니다.
Sample Document: {"x": [1, 2, 3],
"y": 5}
db.foo.createIndex({"x": 1, "y":1})
db.foo.find({"x": 2,
"y": {$gt: 1}}).limit(1)
플래너 버전 2.0은 특히 문서가 8KB를 초과하는 컬렉션에서 여러 필터가 포함된 쿼리의 성능을 개선합니다.
Sample Document: {"x": 2,
"y": 4,
"z": 9,
"t": 99}
db.foo.find({$and: [{"x": {$gt : 1}, "y": {$gt : 3}, "z": {$lt : 10},
"t":{$lt : 100}}]})
플래너 버전 2.0은 정렬 단계를 제거하여 복합 인덱스와 함께 $in 연산자를 사용할 경우의 쿼리 성능을 개선합니다.
Sample Document: {"x": 2,
"y": 4,
"z": 9,
"t": 99}
db.foo.createIndex({"x":1, "y":1})
db.foo.find({"x":2,
"y":$in:[1,2,3,4]}).sort({x:1,y:1})
또한 $in 요소와 함께 다중 키 인덱스를 사용하는 쿼리의 성능을 개선합니다.
Sample Document: {"x": [1, 2, 3]}
db.foo.createIndex({"x": 1})
db.foo.find("x":{$in:[>100 elements]})
- Query performance improvements
-
플래너 버전 2.0은 특히 문서가 8KB를 초과하는 컬렉션에서 여러 필터가 포함된 쿼리의 성능을 개선합니다.
Sample Document: {"x": 2,
"y": 4,
"z": 9,
"t": 99}
db.foo.find({$and: [{"x": {$gt : 1}, "y": {$gt : 3}, "z": {$lt : 10},
"t":{$lt : 100}}]})
플래너 버전 2.0은 정렬 단계를 제거하여 복합 인덱스와 함께 $in 연산자를 사용할 경우의 쿼리 성능을 개선합니다.
Sample Document: {"x": 2,
"y": 4,
"z": 9,
"t": 99}
db.foo.createIndex({"x":1, "y":1})
db.foo.find({"x":2,
"y":$in:[1,2,3,4]}).sort({x:1,y:1})
또한 $in 요소와 함께 다중 키 인덱스를 사용하는 쿼리의 성능을 개선합니다.
Sample Document: {"x": [1, 2, 3]}
db.foo.createIndex({"x": 1})
db.foo.find("x":{$in:[>100 elements]})
계획 캐시 필터 API
텍스트 인덱스는 계획 캐시 필터에서 지원되지 않습니다.
플래너 버전 2.0에는 특정 쿼리 셰이프에서 사용할 수 있는 인덱스 목록을 지정할 수 있는 인덱스 필터 기능에 대한 지원이 추가되었습니다. 이 기능은 API를 통해 액세스할 수 있으며 서버 측에서 제어할 수 있습니다. 쿼리 회귀가 발생하는 경우 이 기능을 사용하면 애플리케이션 코드를 수정하지 않고도 문제를 완화할 수 있는 더 빠르고 유연한 옵션이 제공됩니다.
db.runCommand({ planCacheSetFilter: <collection>, query: <query>,
sort: <sort>, // optional,
indexes: [ <index1>, <index2>, ...],
comment: <any> // optional})
컬렉션의 모든 필터를 나열하려면 다음 명령을 사용합니다.
db.runCommand(
{
planCacheListFilters: <collection>
}
)
이 명령은 컬렉션의 모든 인덱스 필터를 표시합니다. 출력 예시:
{
"filters" : [
{
"query" : {a: "@", b: "@"},
"sort" : {a: 1},
"indexes" : [
<index1>,
...
]
},
...
],
"ok": 1
}
explain 명령 출력에서 indexFilterSet 및 indexFilterApplied의 두 새 필드를 사용하여 플래너 버전 2.0의 인덱스 필터링을 분석할 수 있습니다. 컬렉션에 쿼리 셰이프와 일치하는 인덱스 필터가 설정된 경우는 indexFilterSet는 "true"로 설정됩니다. indexFilterApplied는 쿼리가 인덱스 필터를 적용하고 필터 목록에서 인덱스를 사용하여 계획을 선택한 경우에만 "true"로 설정됩니다.
다음 명령을 사용하여 인덱스 필터를 지울 수 있습니다.
db.runCommand(
{
planCacheClearFilters: <collection>>
query: <query pattern>, // optional
sort: <sort specification>, // optional
comment: <any>. //optional
}
)
"foo" 모음의 모든 필터를 지우려면 다음 명령을 사용합니다.
db.runCommand({planCacheClearFilters: "foo"})
정렬을 사용하여 특정 쿼리 셰이프를 지우려면 planCacheListFilters의 출력에서 쿼리 셰이프를 복사하여 붙여넣으면 됩니다.
db.runCommand({planCacheClearFilters: "foo", query: {a: @}})
정렬 기준으로 지정할 필드가 있는 특정 쿼리 셰이프를 지우려면 planCacheListFilters의 출력에서 쿼리 셰이프를 복사하여 붙여넣으면 됩니다.
db.runCommand({planCacheClearFilters: "foo", query: {a: @},sort: {a: 1}})
플래너 버전 1.0, 2.0 및 MongoDB 간의 잠재적 동작 차이
일부 극단적인 경우에는 플래너 버전 2.0이 MongoDB의 결과와 약간 다른 결과를 생성할 수 있습니다. 이 섹션에서는 이러한 가능성의 몇 가지 예를 살펴봅니다.
- $(update) and $(projection)
-
경우에 따라 MongoDB의 $(update) 및 $(projection) 연산자는 Amazon DocumentDB의 플래너 버전 1.0과 다르게 작동할 수 있습니다. 다음은 일부 예제입니다.
db.students_list.insertMany( [ { _id: 5, student_ids: [ 100, 200 ], grades: [ 95, 100 ], grad_year: [ 2024, 2023 ] } ] )
db.students_list.updateOne({ student_ids: 100, grades: 100, grad_year: 2024 },
{ $set: { “grad_year.$”: 2025 } }
db.col.insert({x:[1,2,3]})
db.col.update({$and:[{x:1},{x:3}]},{$set:{"x.$":500}})
db.col.insert({x:[1,2,3]})
db.col.find()
db.col.insert({x:100})
db.col.update({x:100},{x:100})
플래너 버전 1.0 - nModified 개수 변경
MongoDB - nModified 개수 변경
플래너 버전 2.0 - 동일한 값으로 업데이트해도 nModified 개수는 변경되지 않습니다.
$(update) 연산자를 $setOnInsert와 함께 사용하면 플래너 버전 1.0 및 MongoDB에서 오류가 발생하지만 플래너 버전 2.0에서는 오류가 발생하지 않습니다.
존재하지 않는 필드의 이름을 $field로 변경하면 플래너 버전 2.0에서 오류가 발생하지만 플래너 버전 1.0 및 MongoDB에서는 업데이트를 생성하지 않습니다.
- Index behavior
-
플래너 버전 2.0은 $hint가 적합하지 않은 인덱스와 함께 적용될 때 오류가 발생하지만 플래너 버전 1.0 및 MongoDB에서는 오류가 발생하지 않습니다.
// Insert
db.col.insert({x:1})
db.col.insert({x:2})
db.col.insert({x:3})
// Create index on x with partialFilter Expression {x:{$gt:2}}
db.col.createIndex({x:1},{partialFilterExpression:{x:{$gt:2}}})
// Mongodb allows hint on the following queries
db.col.find({x:1}).hint("x_1")
// result is no documents returned because {x:1} is not indexed by the partial index
// Without $hint mongo should return {x:1}, thus the difference in result between COLSCAN and IXSCAN
DocumentDB will error out when $hint is applied on such cases.
db.col.find({x:1}).hint("x_1")
Error: error: {
"ok" : 0,
"operationTime" : Timestamp(1746473021, 1),
"code" : 2,
"errmsg" : "Cannot use Hint for this Query. Index is multi key index , partial index or sparse index and query is not optimized to use this index."
}
rs0:PRIMARY> db.runCommand({"planCacheSetFilter": "col", "query": { location: {$nearSphere: {$geometry: {type: "Point", coordinates: [1, 1]}}}}, "indexes": ["name_1"]})
{
"ok" : 0,
"operationTime" : Timestamp(1750815778, 1),
"code" : 303,
"errmsg" : "Unsupported query shape for index filter $nearSphere"
}
$near는 플래너 버전 2.0에서 $hint({“$natural”:1})를 사용할 수 없습니다.
// indexes present are index on x and geo index
rs0:PRIMARY> db.usarestaurants.getIndexes()
[
{
"v" : 4,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "test.usarestaurants"
},
{
"v" : 4,
"key" : {
"location" : "2dsphere"
},
"name" : "location_2dsphere",
"ns" : "test.usarestaurants",
"2dsphereIndexVersion" : 1
}
]
// Planner Version 2.0 will throw an error when $hint is applied with index "x_1"
rs0:PRIMARY> db.usarestaurants.find({ "location":{ "$nearSphere":{ "$geometry":{ "type":"Point", "coordinates":[ -122.3516, 47.6156 ] }, "$minDistance":1, "$maxDistance":2000 } } }, { "name":1 }).hint({"$natural": 1})
Error: error: {
"ok" : 0,
"operationTime" : Timestamp(1746475524, 1),
"code" : 291,
"errmsg" : "unable to find index for $geoNear query"
}
// Planner Version 1.0 and MongoDB will not throw an error
db.usarestaurants.find({ "location":{ "$nearSphere":{ "$geometry":{ "type":"Point", "coordinates":[ -122.3516, 47.6156 ] }, "$minDistance":1, "$maxDistance":2000 } } }, { "name":1 }).hint({"$natural": 1})
{ "_id" : ObjectId("681918e087dadfd99b7f0172"), "name" : "Noodle House" }
MongoDB는 전체 정규식 인덱스 스캔을 지원하지만 플래너 버전 2.0은 접두사 필드에서만 정규식 인덱스 스캔을 지원합니다.
// index on x
db.col.createIndex({x:1})
// index scan is used only for prefix regexes
rs0:PRIMARY> db.col.find({x: /^x/}).explain()
{
"queryPlanner" : {
"plannerVersion" : 2,
"namespace" : "test.col",
"winningPlan" : {
"stage" : "IXSCAN",
"indexName" : "x_1",
"direction" : "forward",
"indexCond" : {
"$and" : [
{
"x" : {
"$regex" : /^x/
}
}
]
},
"filter" : {
"x" : {
"$regex" : /^x/
}
}
}
},
"indexFilterSet" : false,
"indexFilterApplied" : false,
"ok" : 1,
"operationTime" : Timestamp(1746474527, 1)
}
// COLSCAN is used for non-prefix regexes
rs0:PRIMARY> db.col.find({x: /x$/}).explain()
{
"queryPlanner" : {
"plannerVersion" : 2,
"namespace" : "test.col",
"winningPlan" : {
"stage" : "COLLSCAN",
"filter" : {
"x" : {
"$regex" : /x$/
}
}
}
},
"indexFilterSet" : false,
"indexFilterApplied" : false,
"ok" : 1,
"operationTime" : Timestamp(1746474575, 1)
플래너 버전 2.0에서 계획 캐시 필터를 사용하는 경우 MongoDB에 비해 몇 가지 고유한 차이점이 있습니다. 플래너 버전 2.0은 계획 캐시 필터를 사용한 “projection” 및 “collation” 지정을 지원하지 않지만 MongoDB에서는 지원합니다. 그러나 MongoDB 인덱스 필터는 인 메모리 전용이며 다시 시작한 후 손실됩니다. 플래너 버전 2.0은 재시작 및 패치를 통해 인덱스 필터를 유지합니다.
- Others
-
플래너 버전 2.0을 사용할 때 DML 감사 로그의 형식은 플래너 버전 1.0과 약간 다릅니다.
command - db.col.find({x:1})
************** Audit logs generated ******************
// v1 format for dml audit logs
{"atype":"authCheck","ts":1746473479983,"timestamp_utc":"2025-05-05 19:31:19.983","remote_ip":"127.0.0.1:47022","users":[{"user":"serviceadmin","db":"test"}],"param":{"command":"find","ns":"test.col","args":{"batchSize":101,"filter":{"x":1},"find":"col","limit":18446744073709551615,"lsid":{"id":{"$binary":"P6RCGz9ZS4iWBSSHWXW15A==","$type":"4"},"uid":{"$binary":"6Jo8PisnEi3dte03+pJFjdCyn/5cGQL8V2KqaoWsnk8=","$type":"0"}},"maxScan":18446744073709551615,"singleBatch":false,"skip":0,"startTransaction":false},"result":0}}
// v2 formal for dml audit logs
{"atype":"authCheck","ts":1746473583711,"timestamp_utc":"2025-05-05 19:33:03.711","remote_ip":"127.0.0.1:37754","users":[{"user":"serviceadmin","db":"test"}],"param":{"command":"find","ns":"test.col","args":{"find":"col","filter":{"x":1},"lsid":{"id":{"$binary":"nJ88TGCSSd+BeD2+ZtrhQg==","$type":"4"}},"$db":"test"},"result":0}}
-
설명 계획의 일부로 사용되는 인덱스 조건:
rs0:PRIMARY> db.col.createIndex({index1:1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1,
"operationTime" : Timestamp(1761149251, 1)
}
플래너 버전 2.0은 인덱스 조건 및 필터를 표시하는 계획 출력을 설명합니다.
rs0:PRIMARY> db.col.find({$and:[{price:{$eq:300}},{item:{$eq:"apples"}}]}).explain()
{
"queryPlanner" : {
"plannerVersion" : 2,
"namespace" : "test.col",
"winningPlan" : {
"stage" : "IXSCAN",
"indexName" : "price_1",
"direction" : "forward",
"indexCond" : {
"$and" : [
{
"price" : {
"$eq" : 300
}
}
]
},
"filter" : {
"$and" : [
{
"item" : {
"$eq" : "apples"
}
}
]
}
}
},
"indexFilterSet" : false,
"indexFilterApplied" : false,
"ok" : 1,
"operationTime" : Timestamp(1761149497, 1)
}
플래너 버전 1.0은 계획 출력을 설명합니다.
rs0:PRIMARY> db.col.find({$and:[{price:{$eq:300}},{item:{$eq:"apples"}}]}).explain()
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "test.col",
"winningPlan" : {
"stage" : "IXSCAN",
"indexName" : "price_1",
"direction" : "forward"
}
},
"ok" : 1,
"operationTime" : Timestamp(1761149533, 1)
}
플래너 버전 2.0은 동작 격차를 MongoDB와 연결합니다.
플래너 버전 2.0이 MongoDB의 동작 격차를 해소하는 몇 가지 영역이 있습니다.
플래너 버전 2.0은 $elemMatch의 평면화된 배열에서 숫자 인덱스 조회를 허용합니다.
doc: {"x" : [ [ { "y" : 1 } ] ] }
// Planner Version 2 and mongo
> db.bar.find({"x.0": {$elemMatch: {y: 1}}})
{ "_id" : ObjectId("68192947945e5846634c455a"), "x" : [ [ { "y" : 1 } ] ] }
> db.bar.find({"x": {$elemMatch: {"0.y": 1}}})
{ "_id" : ObjectId("68192947945e5846634c455a"), "x" : [ [ { "y" : 1 } ] ] }
//Whereas Planner Version 1 wouldn't return any results.
> db.bar.find({"x.0": {$elemMatch: {y: 1}}})
> db.bar.find({"x": {$elemMatch: {"0.y": 1}}})
플래너 버전 1.0은 프로젝션에서 문자열을 제외했지만 플래너 버전 2.0의 동작은 MongoDB와 일치하고 이를 리터럴 값으로 취급합니다.”
// Planner V2/ MongoDB
> db.col.find()
{ "_id" : ObjectId("681537738aa101903ed2fe05"), "x" : 1, "y" : 1 }
> db.col.find({},{x:"string"})
{ "_id" : ObjectId("681537738aa101903ed2fe05"), "x" : "string" }
// Planner V1 treats strings as exclude in projection
rs0:PRIMARY> db.col.find()
{ "_id" : ObjectId("68153744d42969f11d5cca72"), "x" : 1, "y" : 1 }
rs0:PRIMARY> db.col.find({},{x:"string"})
{ "_id" : ObjectId("68153744d42969f11d5cca72"), "y" : 1 }
MongoDB와 같은 플래너 버전 2.0은 동일한 필드 “x” 및 “x.a”에서 프로젝션을 허용하지 않습니다.
// Planner version 2/MongoDB will error out
> db.col.find()
{ "_id" : ObjectId("68153da2012265816bc9ba23"), "x" : [ { "a" : 1 }, 3 ] }
db.col.find({},{"x.a":1,"x":1}) // error
// Planner Version 1 does not error out
db.col.find()
{ "_id" : ObjectId("68153da2012265816bc9ba23"), "x" : [ { "a" : 1 }, 3 ] }
db.col.find({},{"x.a":1,"x":1})
{ "_id" : ObjectId("68153d60143af947c720d099"), "x" : [ { "a" : 1 }, 3 ] }
MongoDB와 같은 플래너 버전 2.0은 하위 문서에 대한 프로젝션을 허용합니다.
// Planner Version2/MongoDB supports projections on subdocuments
db.col.find()
{ "_id" : ObjectId("681542d8f35ace71f0a50004"), "x" : [ { "y" : 100 } ] }
> db.col.find({},{"x":{"y":1}})
{ "_id" : ObjectId("681542b7a22d548e4ac9ddea"), "x" : [ { "y" : 100 } ] }
// Planner V1 throws error if projection is subdocument
db.col.find()
{ "_id" : ObjectId("681542d8f35ace71f0a50004"), "x" : [ { "y" : 100 } ] }
rs0:PRIMARY> db.col.find({},{"x":{"y":1}})
Error: error: {
"ok" : 0,
"operationTime" : Timestamp(1746223914, 1),
"code" : 2,
"errmsg" : "Unknown projection operator y"
}
MongoDB와 같은 플래너 버전 2.0에서는 프로젝션이 $ 연산자 이후의 필드를 지원하지 않습니다.
// Mongo and Planner Version 2 will error out
db.col.find()
{ "_id" : ObjectId("68155fa812f843439b593f3f"), "x" : [ { "a" : 100 } ] }
db.col.find({"x.a":100},{"x.$.a":1}) - // error
// v1 will not error out
db.col.find()
{ "_id" : ObjectId("68155fa812f843439b593f3f"), "x" : [ { "a" : 100 } ] }
db.col.find({"x.a":100},{"x.$.a":1})
{ "_id" : ObjectId("68155dee13b051d58239cd0a"), "x" : [ { "a" : 100 } ] }
MongoDB와 같은 플래너 버전 2.0에서는 $hint를 사용할 수 있습니다.
// v1 will error out on $hint if there are no filters
db.col.find({}).hint("x_1")
Error: error: {
"ok" : 0,
"operationTime" : Timestamp(1746466616, 1),
"code" : 2,
"errmsg" : "Cannot use Hint for this Query. Index is multi key index , partial index or sparse index and query is not optimized to use this index."
}
// Mongo and Planner Version 2 will allow $hint usage
db.col.find({}).hint("x_1")
{ "_id" : ObjectId("6818f790d5ba9359d68169cf"), "x" : 1 }