mongoDB의 문자열 필드 값 길이
필드의 데이터 유형은 String입니다.필드 이름의 문자 길이가 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 이후의 경우:
연산자는 쿼리 언어 내에서 집약식을 사용할 수 있으므로 연산자를 사용하여 다음과 같이 문자열 길이를 확인할 수 있습니다.
db.usercollection.find({
name: { $exists: true },
$expr: { $gt: [{ $strLenCP: '$name' }, 40] }
})
MongoDB 3.4 이후의 경우:
또한 파이프라인 연산자와 함께 집계 프레임워크를 사용하여 논리 조건을 처리하고 특수 작업을 사용하여 논리 조건이 참인 문서를 "보관"하거나 조건이 거짓인 문서를 "제거"할 수 있습니다.
이 작업은 컬렉션에서 필드를 선택하고 논리 조건 쿼리의 결과를 보관하는 새 필드를 생성하는 파이프라인과 유사하지만 이 작업에서는 보다 효율적인 단일 파이프라인 단계를 사용합니다.
논리 조건에 대해서는 연산자를 사용하여 문자열 길이를 확인할 수 있는 String Aggregation 연산자가 있습니다.길이가 지정된 값인 경우, 이는 진정한 일치이며 문서는 "kept"입니다.그렇지 않으면 "자른" 상태로 폐기됩니다.
상기의 개념을 나타내는 다음의 집약 조작을 실행하는 것을 검토해 주십시오.
db.usercollection.aggregate([
{ $match: { name: { $exists: true } } },
{ $redact: {
$cond: [
{ $gt: [ { $strLenCP: "$name" }, 40] },
"$$KEEP",
"$$PRUNE"
]
} },
{ $limit: 2 }
])
를 사용하는 경우 괄호 없이 쿼리를 시도합니다.
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.$where질의문은 색인을 사용할 수 있습니다.보다 뛰어난 퍼포먼스는 문자열의 길이를 다른 필드로 저장한 후 인덱싱 또는 검색할 수 있습니다.이것에 비해 적용에 시간이 걸립니다.다른 방법으로 데이터를 구조화할 수 없거나 데이터의 작은 서브셋을 처리할 때 마지막 수단으로 JavaScript 식과 연산자를 사용하는 것이 좋습니다.
오퍼레이터의 사용을 회피하는 다른 고속 접근방식은 오퍼레이터입니다.다음 패턴을 고려하여 다음 패턴을 검색합니다.
db.usercollection.find({"name": {"$type": 2, "$regex": /^.{41,}$/}}).limit(2);
참고 - 문서에서:
필드에 인덱스가 존재하는 경우 MongoDB는 인덱스의 값과 정규식을 대조합니다.이 값은 수집 스캔보다 빠를 수 있습니다.정규 표현이 "prefix expression"인 경우 추가 최적화가 발생할 수 있습니다. 즉, 모든 일치 가능성이 동일한 문자열로 시작됩니다.이것에 의해, MongoDB 는 그 프리픽스에서 「범위」를 작성해, 그 범위에 포함되는 인덱스의 값에 대해서만 일치시킬 수 있습니다.
은 캐럿으로 식입니다.
(^)"" " " " " " "(\A)나옵니다.들어 regex 입니다./^abc.*/값 중 "로 시작하는 됩니다.abc.★에서는,
/^a/, /^a.*/,★★★★★★★★★★★★★★★★★」/^a.*$/일치하는 문자열은 서로 다른 성능 특성을 가집니다.은 모두 존재하는 「인덱스」는, 「인덱스」를 사용합니다./^a.*/, , , , 입니다./^a.*$/더 느리다./^a/는 프리픽스를 일치시킨 후에 스캔을 정지할 수 있습니다.
「」를 사용한 $where ★★★★★★★★★★★★★★★★★」$expr문서가 너무 많으면 느려집니다.
「」를 사용합니다.$regex가 훨씬 빠르다$where,$expr.
db.usercollection.find({
"name": /^[\s\S]{40,}$/, // name.length >= 40
})
or
db.usercollection.find({
"name": { "$regex": "^[\s\S]{40,}$" }, // name.length >= 40
})
이 쿼리는 다음과 같은 의미입니다.
db.usercollection.find({
"$where": "this.name && this.name.length >= 40",
})
or
db.usercollection.find({
"name": { "$exists": true },
"$expr": { "$gte": [ { "$strLenCP": "$name" }, 40 ] }
})
나는 내 수집품에 대해 각 쿼리를 테스트했다.
# find
$where: 10529.359ms
$expr: 5305.801ms
$regex: 2516.124ms
# count
$where: 10872.006ms
$expr: 2630.155ms
$regex: 158.066ms
여기 mongodb에서 이것을 달성할 수 있는 방법 중 하나가 있다.
db.usercollection.find({ $where: 'this.name.length < 4' })
이 쿼리는 필드 값과 길이를 모두 제공합니다.
db.usercollection.aggregate([
{
$project: {
"name": 1,
"length": { $strLenCP: "$name" }
}} ])
저도 비슷한 시나리오였지만, 제 경우 문자열은 1레벨 속성이 아닙니다.그것은 물건 안에 있다.여기서는 그것에 대한 적절한 답을 찾을 수 없었다.그래서 저는 저의 해결책을 여러분들과 공유하고 싶었습니다(이것이 비슷한 종류의 문제를 가진 모든 사람에게 도움이 되기를 바랍니다).
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;
}
}})
「 」로 .name 40자 이상:
db.usercollection.find({name: /.{40}/})
(카라사와 후미야의 답변에서 RegEx를 간략화)
언급URL : https://stackoverflow.com/questions/29577713/string-field-value-length-in-mongodb
'programing' 카테고리의 다른 글
| Rails 앱 내에서 JSON API 호출하기 (0) | 2023.02.22 |
|---|---|
| console.log(결과)는 [Object]를 인쇄합니다.result.name에 접속하려면 어떻게 해야 하나요? (0) | 2023.02.22 |
| 데이터 URI에 대한 Ajax 요청의 원시 이미지 데이터 사용 (0) | 2023.02.22 |
| 판매가격이 없는 경우 woocommerce 판매가격 또는 정가를 표시하는 방법 (0) | 2023.02.22 |
| JavaScript를 사용하여 JSON 오브젝트 트리의 모든 노드 트래버스 (0) | 2023.02.22 |