IT Share you

mongoDB의 문자열 필드 값 길이

shareyou 2020. 12. 3. 20:52
반응형

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

반응형