mongoDB의 문자열 필드 값 길이
필드의 데이터 유형은 문자열입니다. 필드 이름의 문자 길이가 40보다 큰 데이터를 가져오고 싶습니다.
이 쿼리를 시도했지만 오류가 반환되었습니다. 1.
db.usercollection.find(
{$where: "(this.name.length > 40)"}
).limit(2);
output :error: {
"$err" : "TypeError: Cannot read property 'length' of undefined near '40)' ",
"code" : 16722
}
이것은 2.4.9에서 작동하지만 내 버전은 2.6.5입니다.
MongoDB 3.6 이상 :
이 $expr
연산자를 사용하면 쿼리 언어 내에서 집계 식을 사용할 수 있으므로 연산자를 사용하여 $strLenCP
다음과 같이 문자열 길이를 확인할 수 있습니다.
db.usercollection.find({
"name": { "$exists": true },
"$expr": { "$gt": [ { "$strLenCP": "$name" }, 40 ] }
})
MongoDB 3.4 이상 :
또한 $redact
파이프 라인 연산자 와 함께 집계 프레임 워크를 사용하여 연산자로 논리 조건을 처리 할 $cond
수 있고 특수 연산 $$KEEP
을 사용 하여 논리 조건이 참인 문서를 "유지"하거나 조건이 $$PRUNE
있는 문서를 "제거"할 수 있습니다. 그릇된.
이 작업은 더 효율적인 단일 파이프 라인 단계를 사용 한다는 점을 제외하고 는 $project
컬렉션의 필드를 선택하고 논리적 조건 쿼리의 결과를 보관하는 새 필드를 만든 다음 후속를 만드는 파이프 라인 을 갖는 것과 유사합니다 .$match
$redact
논리적 조건에 관해서는 연산자를 사용 하여 문자열의 길이를 확인할 수 있는 문자열 집계 연산자 가 있습니다 $strLenCP
. 길이가 $gt
지정된 값이면 실제 일치이며 문서는 "유지"됩니다. 그렇지 않으면 "가지 치기"되고 버려집니다.
위의 개념을 보여주는 다음 집계 작업을 실행 해보십시오.
db.usercollection.aggregate([
{ "$match": { "name": { "$exists": true } } },
{
"$redact": {
"$cond": [
{ "$gt": [ { "$strLenCP": "$name" }, 40] },
"$$KEEP",
"$$PRUNE"
]
}
},
{ "$limit": 2 }
])
를 사용하는 경우 $where
괄호를 묶지 않고 쿼리를 시도하십시오.
db.usercollection.find({$where: "this.name.length > 40"}).limit(2);
더 나은 쿼리는 필드의 존재를 확인한 다음 길이를 확인하는 것입니다.
db.usercollection.find({name: {$type: 2}, $where: "this.name.length > 40"}).limit(2);
또는:
db.usercollection.find({name: {$exists: true}, $where: "this.name.length >
40"}).limit(2);
MongoDB는 표현식과 비 쿼리 문이 인덱스를 사용 $where
하기 전에 비 쿼리 작업을 평가 합니다. 훨씬 더 나은 성능은 문자열의 길이를 다른 필드로 저장 한 다음 색인화하거나 검색 할 수있는 것입니다. 적용 은 그것에 비해 훨씬 느릴 것입니다. 다른 방식으로 데이터를 구조화 할 수 없거나 데이터의 작은 하위 집합을 처리 할 때 마지막 수단으로 JavaScript 표현식과 연산자 를 사용하는 것이 좋습니다 .$where
$where
$where
$where
$where
운영자 의 사용을 피하는 다른 더 빠른 접근 방식 은 $regex
운영자입니다. 검색하는 다음 패턴을 고려하십시오.
db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2);
참고 - 문서에서 :
필드에 대한 인덱스가 있으면 MongoDB는 인덱스의 값에 대해 정규식을 일치시켜 컬렉션 스캔보다 빠를 수 있습니다. 정규 표현식이 "접두어 표현식"인 경우 추가 최적화가 발생할 수 있습니다. 이는 모든 잠재적 일치가 동일한 문자열로 시작 함을 의미합니다. 이를 통해 MongoDB는 해당 접두사에서 "범위"를 구성하고 해당 범위에 속하는 인덱스의 값과 만 일치시킬 수 있습니다.
정규 표현식은 캐럿
(^)
또는 왼쪽 앵커(\A)
로 시작하고 그 뒤에 간단한 기호 문자열이 오는 경우 "접두어 표현식" 입니다. 예를 들어 정규식/^abc.*/
은로 시작하는 인덱스의 값에 대해서만 일치하여 최적화됩니다abc
.또한 동등한 문자열
/^a/, /^a.*/,
과/^a.*$/
일치하는 동안 성능 특성이 다릅니다. 이러한 모든 표현식은 적절한 색인이있는 경우 색인을 사용합니다. 그러나,/^a.*/
및/^a.*$/
속도가 느립니다./^a/
접두사를 일치시킨 후 검색을 중지 할 수 있습니다.
mongodb에서 이것을 달성 할 수있는 방법 중 하나가 있습니다.
db.usercollection.find({ $where: 'this.name.length < 4' })
비슷한 종류의 시나리오가 있었지만 제 경우에는 문자열이 첫 번째 수준 속성이 아닙니다. 개체 내부에 있습니다. 여기에서는 적절한 답을 찾을 수 없습니다. 그래서 나는 내 해결책을 여러분 모두와 공유하려고 생각했습니다 (비슷한 종류의 문제를 가진 사람에게 도움이되기를 바랍니다).
Parent Collection
{
"Child":
{
"name":"Random Name",
"Age:"09"
}
}
예 : 자녀 이름의 길이가 10 자 이상인 컬렉션 만 가져와야하는 경우.
db.getCollection('Parent').find({$where: function() {
for (var field in this.Child.name) {
if (this.Child.name.length > 10)
return true;
}
}})
와 쿼리 $where
와는 $expr
너무 많은 문서가있는 경우 느리다.
Using $regex
is much faster than $where
, $expr
.
db.usercollection.find({
"name": /^[\s\S]{40,}$/, // name.length >= 40
})
or
db.usercollection.find({
"name": { "$regex": "^[\s\S]{40,}$" }, // name.length >= 40
})
This query is the same meaning with
db.usercollection.find({
"$where": "this.name && this.name.length >= 40",
})
or
db.usercollection.find({
"name": { "$exists": true },
"$expr": { "$gte": [ { "$strLenCP": "$name" }, 40 ] }
})
I tested each queries for my collection.
# find
$where: 10529.359ms
$expr: 5305.801ms
$regex: 2516.124ms
# count
$where: 10872.006ms
$expr: 2630.155ms
$regex: 158.066ms
This query will give both field value and length:
db.usercollection.aggregate([
{
$project: {
"name": 1,
"length": { $strLenCP: "$name" }
}} ])
참고URL : https://stackoverflow.com/questions/29577713/string-field-value-length-in-mongodb
'IT Share you' 카테고리의 다른 글
메모리의 목록 크기 (0) | 2020.12.03 |
---|---|
예상되는 예외없이 테스트 (0) | 2020.12.03 |
디자인 지원 라이브러리의 TabLayout에서 탭 간 구분선을 설정하는 방법은 무엇입니까? (0) | 2020.12.03 |
logcat 또는 예외없이 Android 앱이 충돌 함 (0) | 2020.12.03 |
VS 코드 : .git 폴더 / 파일 숨김 (0) | 2020.12.03 |