MongoDB는 $exists 연산자로 필드의 존재를 확인할 때 인덱스를 사용할 수 있습니까?
데이터가 있는 경우users
다음과 같은 컬렉션:
{ name: '...',
email: '...',
...,
photos: {
123: { url: '...', title: '...', ... },
456: { url: '...', title: '...', ... },
...
}
}
그리고 어떤 사용자가 사진 ID 127을 소유하고 있는지 알고 싶으며, 다음과 같은 질문을 사용합니다.
db.users.find( {'photos.127': {'$exists' => true} } );
시도해봤지만 MongoDB가 이 쿼리에 인덱스를 사용하도록 하는 것은 불가능할 것 같습니다.제가 시도한 지수는 다음과 같습니다.db.users.ensureIndex({photos:1});
그리고 제가 사용했을 때explain()
mongo는 BasicCursor(즉, 인덱스가 사용되지 않음)를 사용하고 있다고 말했습니다.
mongo가 이 쿼리에 사용할 인덱스를 만들 수 있습니까?
업데이트됨:
보이다$exists
쿼리가 이제 이러한 티켓을 기반으로 인덱스를 올바르게 사용함 $valid 쿼리는 인덱스를 사용해야 하며 {$valid:false}은(는) 인덱스를 사용하지 않습니다.
이전 답변:
아니요, mongodb에게 기존 쿼리에 인덱스를 사용하도록 지시할 방법이 없습니다.인덱싱은 데이터와 완전히 관련되어 있습니다.$exists는 키(필드)에만 관련되므로 인덱스에 사용할 수 없습니다.
$filename은 지정된 키(또는 필드)가 문서에 존재하는지 여부만 확인합니다.
$208은 인덱스를 사용하지 않지만 데이터 구조를 다음으로 변경할 수 있습니다.
photos: [
{id:123, url: '...', title: '...', ... },
{id:456, url: '...', title: '...', ... },
...
]
그런 다음 사용합니다.
db.users.ensureIndex({photos.id:1})
사진 ID에 대한 인덱스를 만듭니다.
제가 틀린 것 같습니다. 사실 $exists 쿼리에서 인덱스를 사용하도록 강제할 수 있습니다.위의 구조를 사용하여 계속 진행해 보겠습니다. 하지만 귀하의 사진 ID는 확실히 포함되어 있지 않습니다. 즉, 일부 문서는 'ID' 키를 가지고 있고 일부 문서는 그렇지 않습니다.그런 다음 해당 인덱스에 스파스 인덱스를 생성할 수 있습니다.
db.users.ensureIndex({'photos.id': 1}, {'sparse': true})
그런 다음 다음과 같이 질문합니다.
db.users.find({'photos.id': {$exists: true}}).hint({'photos.id': 1})
쿼리가 인덱스를 사용하고 있는지 확인하기 위해 설명을 추가할 수 있습니다.다음은 제 결과입니다. 제 컬렉션의 모바일 키는 귀하의 photos.id 와 비슷합니다.
> db.test.count()
50000
> db.test.find({'mobile': {$exists: true}}).hint({'mobile': 1}).explain()
{
"cursor" : "BtreeCursor mobile_1",
"nscanned" : 49999,
"nscannedObjects" : 49999,
"n" : 49999,
"millis" : 138,
"nYields" : 0,
"nChunkSkips" : 0,
"isMultiKey" : false,
"indexOnly" : false,
"indexBounds" : {
"mobile" : [
[
{
"$minElement" : 1
},
{
"$maxElement" : 1
}
]
]
}
}
> db.test.getIndexes()
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"ns" : "test.test",
"name" : "_id_"
},
{
"v" : 1,
"key" : {
"mobile" : 1
},
"ns" : "test.test",
"name" : "mobile_1",
"sparse" : true,
"background" : true
}
]
도움이 되길 바랍니다!
MongoDB 2.0 이후 $exists
쿼리는 인덱스를 사용해야 합니다.불행하게도 이 수정은 최신 버전에서 사라졌고 MongoDB 2.5에서 수정될 것입니다.
2022년 6월 현재 이 지수는 다음에 사용할 수 없습니다.${exists: true}
case 및 는 다른 사례의 절반에 대해서만 부분적으로만 사용할 수 있습니다.MongoDB 인덱스에 대한 주요(IMO) 설계 버그가 있어 아직까지 사람들이 잘 알지 못하는 경우가 있어 해결책을 제시하여 이 답변을 게시합니다.
문제는 MongoDB가 존재하지 않는 필드를 다음과 같이 인덱싱한다는 것입니다.null
그리고 이 필드들은 와 구별할 수 없습니다.null
지수 관점에서 s.게다가 JS 유추와 관련된 약간의 혼란이 있습니다.undefined === null
이지만 거이지입니다.undefined == null
사실입니다.즉, 다음과 같습니다.
- 을 할 때
{$exists: false}
인덱스를 사용할 수 있습니다.null 값과 존재하지 않는 값이 모두 인덱스에서 스캔되고 문서가 가져오고 null과 동일한 값이 필터링됩니다.해당 MongoDB 단계:[null, null] IXSCAN
그리고.FETCH with {"$not" : {$exists: true}} filter
. - 을 할 때
{field: null}
인덱스를 사용할 수 있습니다.그러기 위해서는 인덱스 스캔만 하면 됩니다.MongoDB는 그것을 다음과 같이 해석합니다.{field: { $eq: null }}
역사적인 이유로 Mongo는 더 이상 사용되지 않는 것을 찾기도 합니다.undefined
유값/형:[undefined, undefined]U[null, null] IXSCAN
IMO는 평등을 가치 평등으로 해석하고 결과에 존재하지 않는 필드를 포함하지 않는 것이 훨씬 논리적일 것입니다.하지만 그것은 사실입니다. - null과 .
field: {$type: "null"}
인덱스를 사용할 수 있습니다.첫 번째 경우와 마찬가지로 단계는 다음과 같습니다.[null, null] IXSCAN
그리고.FETCH with {'$type': [10]} filter
필드가 없는 값은 불필요하게 가져온 다음 필터링됩니다. - 모든 기존 값을 검색해야 하는 경우(예: 값이 있는 값 포함)
null
그러면 당신은 불운합니다.검색 쿼리는 다음과 같습니다.{field: {$exists: true}}
인덱스를 사용할 수 없습니다.mongo가 인덱스를 사용하고 있다면 다음과 같이 인덱스된 값을 포함할 것입니다.null
필드가 null인 문서를 포함하고 나중에 존재하지 않는 값을 필터링합니다.따라서 전체 인덱스가 필요하므로 전체 수집 검색이 더 효율적입니다.Mongo 단계계:COLLSCAN with { '$exists': true } filter
. - 다음과 같은 값 없이 살 수 있는 경우
null
즉, 포지않됩니다아도하를 포함하지 않아도 .$type: null
결과에서 인덱스를 사용할 수 있습니다.필드 유형이 e.g.인 경우ObjectId를 검색할 수 있습니다.{field: {$type: "object"}}
: 유형목록목:{field: {$type: ["number", "object"]}}
아니면 그냥{field: {$ne: "null"}}
후자는 제외할 것입니다.null
그리고.undefined
유형을 입력합니다.Mongo 단계는 다음과 같습니다.[{},[]) IXSCAN
그리고.FETCH
'[nan.0, inf.0]U[{}, [])'
그리고.FETCH
[MinKey, undefined)U(null, MaxKey] IXSCAN
그리고.FETCH
.
2014년 2월에 접수된 문제가 있습니다: https://jira.mongodb.org/browse/SERVER-12869 .안타깝게도 MongoDB는 아직 이 문제의 우선순위를 정하지도 않았고, 공식 문서에도 이 문제를 반영하지도 않았습니다.
2023년 2월 현재 최신 변경 사항과 함께 여기에 게시 - 인덱스와 함께 $209를 사용하려면 여기 표를 참조하는 것이 좋습니다. https://www.mongodb.com/docs/manual/reference/operator/query/exists/
{$exists: true} 쿼리에 인덱스를 사용하려면 스파스 인덱스를 사용하는 것이 가장 좋습니다.
언급URL : https://stackoverflow.com/questions/8176310/can-mongodb-use-an-index-when-checking-for-existence-of-a-field-with-exists-ope
'it-source' 카테고리의 다른 글
한 워크북의 시트에서 다른 워크북으로 VBA 코드를 복사하시겠습니까? (0) | 2023.07.15 |
---|---|
iOS 시뮬레이터 내에서 앱스토어에 액세스할 수 있습니까? (0) | 2023.07.15 |
Asp.net Core에서 웹 UI를 만드는 데 레이저 페이지가 권장되는 이유는 무엇입니까? (0) | 2023.07.15 |
SQL Server에서 SqlDataReader로 데이터를 가져오는 방식은 무엇입니까? (0) | 2023.07.15 |
Postgre를 사용하여 DataJpaTest 실행SQL (0) | 2023.07.15 |