두 필드 비교 시 MongoDb 쿼리 조건
컬렉션이 있습니다.T
, 2개의 필드가 있습니다.Grade1
그리고.Grade2
조건이 있는 것을 선택하고 싶다.Grade1 > Grade2
MySQL과 같은 쿼리를 받으려면 어떻게 해야 하나요?
Select * from T Where Grade1 > Grade2
$를 사용할 수 있습니다.(모든 레코드에서 Javascript 코드를 실행해야 함) 상당히 느리므로 가능하면 인덱스된 쿼리와 결합할 수 있습니다.
db.T.find( { $where: function() { return this.Grade1 > this.Grade2 } } );
콤팩트 이상:
db.T.find( { $where : "this.Grade1 > this.Grade2" } );
mongodb v.3.6+용 UPD
사용할 수 있습니다.$expr
최근의 회답에서 기술한 바와 같이
$expr(3.6 mongo 버전 연산자)을 사용하여 일반 쿼리에서 집약 함수를 사용할 수 있습니다.
와 비교합니다.
정기 쿼리:
db.T.find({$expr:{$gt:["$Grade1", "$Grade2"]}})
집약 쿼리:
db.T.aggregate({$match:{$expr:{$gt:["$Grade1", "$Grade2"]}}})
쿼리가 연산자로만 구성되어 있는 경우 JavaScript 식만 전달할 수 있습니다.
db.T.find("this.Grade1 > this.Grade2");
성능을 향상시키려면 지정된 조건을 충족하는 문서를 필터링하는 파이프라인이 있는 집계 작업을 실행하십시오.
파이프라인은 필드 수준 수정 및 필드 수준 수정의 기능을 통합하며, 여기서 필드 수준 수정은 를 사용하여 조건에 일치하는 모든 문서를 반환하고 파이프라인 결과에서 변수를 사용하여 일치하지 않는 문서를 제거합니다.
다음 집약 조작 필터를 실행하면 대규모 컬렉션에 사용하는 것보다 문서를 효율적으로 실행할 수 있습니다.이 필터에서는 에서 JavaScript 평가를 사용하는 것이 아니라 단일 파이프라인 및 네이티브 MongoDB 연산자를 사용하기 때문에 쿼리가 느려질 수 있습니다.
db.T.aggregate([
{
"$redact": {
"$cond": [
{ "$gt": [ "$Grade1", "$Grade2" ] },
"$$KEEP",
"$$PRUNE"
]
}
}
])
2개의 파이프라인을 통합한 보다 간단한 버전입니다.
db.T.aggregate([
{
"$project": {
"isGrade1Greater": { "$cmp": [ "$Grade1", "$Grade2" ] },
"Grade1": 1,
"Grade2": 1,
"OtherFields": 1,
...
}
},
{ "$match": { "isGrade1Greater": 1 } }
])
MongoDB 3.4 이후의 경우:
db.T.aggregate([
{
"$addFields": {
"isGrade1Greater": { "$cmp": [ "$Grade1", "$Grade2" ] }
}
},
{ "$match": { "isGrade1Greater": 1 } }
])
읽기 쉬움보다 성능이 더 중요하고 조건이 단순한 산술 연산으로 구성되어 있는 경우 집약 파이프라인을 사용할 수 있습니다.먼저 $project를 사용하여 조건의 왼쪽을 계산합니다(모든 필드를 왼쪽으로 이동).그런 다음 $match를 사용하여 상수 및 필터와 비교합니다.이렇게 하면 Javascript 실행을 피할 수 있습니다.다음은 python에 대한 테스트입니다.
import pymongo
from random import randrange
docs = [{'Grade1': randrange(10), 'Grade2': randrange(10)} for __ in range(100000)]
coll = pymongo.MongoClient().test_db.grades
coll.insert_many(docs)
집약 사용:
%timeit -n1 -r1 list(coll.aggregate([
{
'$project': {
'diff': {'$subtract': ['$Grade1', '$Grade2']},
'Grade1': 1,
'Grade2': 1
}
},
{
'$match': {'diff': {'$gt': 0}}
}
]))
1루프, 1루프 베스트: 192밀리초/루프
찾기 및 $where 사용:
%timeit -n1 -r1 list(coll.find({'$where': 'this.Grade1 > this.Grade2'}))
1루프, 1루프당 베스트: 4.54초
언급URL : https://stackoverflow.com/questions/4442453/mongodb-query-condition-on-comparing-2-fields
'programing' 카테고리의 다른 글
URL에서 JSON 문자열을 가져오려면 어떻게 해야 합니까? (0) | 2023.04.02 |
---|---|
주의: /var/www/html/mytheme/wp-includes/formating에서의 배열에서 문자열로의 변환.1025행의 php (0) | 2023.04.02 |
html에서 제출을 클릭하고 php 코드를 실행합니다. (0) | 2023.04.02 |
SQL - 계층 저장 및 탐색 방법 (0) | 2023.04.02 |
TypeScript에서 함수의 반환 유형을 선언하는 방법 (0) | 2023.04.02 |