복붙노트

[MONGODB] 이 개 필드를 비교에 MongoDB의 쿼리 조건

MONGODB

이 개 필드를 비교에 MongoDB의 쿼리 조건

나는이 개 필드 모음 T,이 : Grade1 및 Grade2을, 그리고 내가 MySQL은 같은 쿼리를 얻을 수있는 방법, 조건 Grade1> Grade2있는 사람을 선택하려면?

Select * from T Where Grade1 > Grade2

해결법

  1. ==============================

    1.당신은 어디에 $를 사용할 수 있습니다. 그냥 상당히 느려집니다 인식 할 수 있다면 그렇게 인덱스 쿼리와 결합 (모든 레코드에 자바 스크립트 코드를 실행할 수있다).

    당신은 어디에 $를 사용할 수 있습니다. 그냥 상당히 느려집니다 인식 할 수 있다면 그렇게 인덱스 쿼리와 결합 (모든 레코드에 자바 스크립트 코드를 실행할 수있다).

    db.T.find( { $where: function() { return this.Grade1 > this.Grade2 } } );
    

    이상의 소형 :

    db.T.find( { $where : "this.Grade1 > this.Grade2" } );
    

    최근의 대답에 설명 된대로 $ EXPR을 사용할 수 있습니다

  2. ==============================

    2.쿼리는 경우에만 연산자 $로 구성된 경우, 당신은 자바 스크립트 표현에 전달할 수 있습니다 :

    쿼리는 경우에만 연산자 $로 구성된 경우, 당신은 자바 스크립트 표현에 전달할 수 있습니다 :

    db.T.find("this.Grade1 > this.Grade2");
    

    더 큰 성능을 위해, 주어진 조건을 만족하는 문서를 필터링 달러 (A $)의 편집하다 파이프 라인을 가지고 집계 작업을 실행합니다.

    은 $ 편집하다 파이프 라인은 $ 프로젝트의 기능과는 $$의 PRUNE 변수를 사용하여 일치하지 않는 그 결과 파이프 라인에서 $$ 유지하고 제거합니다을 사용하는 조건과 일치하는 모든 문서를 반환 할 경우 필드 레벨 교정을 구현하는 $ 일치하는 항목을 포함한다.

    큰 컬렉션이 쿼리 속도가 느려질 수, 하나의 파이프 라인 및 기본 MongoDB를 사업자가 아닌 $와 자바 스크립트의 평가를 사용하기 때문에 어디에서 $를 사용하는 것보다 더 효율적으로 다음과 같은 집계 작업 필터에게 문서를 실행 :

    db.T.aggregate([
        {
            "$redact": {
                "$cond": [
                    { "$gt": [ "$Grade1", "$Grade2" ] },
                    "$$KEEP",
                    "$$PRUNE"
                ]
            }
        }
    ])
    

    이는 두 개의 파이프 라인 $ 프로젝트와 $ 일치하는 통합의보다 단순화 된 버전입니다 :

    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 } }
    ])
    
  3. ==============================

    3.당신은 일반 쿼리에서 집계 함수를 사용하여 $ EXPR (3.6 몽고 버전 연산자)를 사용할 수 있습니다.

    당신은 일반 쿼리에서 집계 함수를 사용하여 $ EXPR (3.6 몽고 버전 연산자)를 사용할 수 있습니다.

    집계 비교 연산자 대 쿼리 연산자를 비교.

    일반 검색어 :

    db.T.find({$expr:{$gt:["$Grade1", "$Grade2"]}})
    

    집계 쿼리 :

    db.T.aggregate({$match:{$expr:{$gt:["$Grade1", "$Grade2"]}}})
    
  4. ==============================

    4.경우 성능은 가독성보다 더 중요하고 한 당신의 상태는 간단한 산술 연산으로 구성되어, 당신은 집계 파이프 라인을 사용할 수 있습니다. 첫째, 조건 (왼쪽에 모든 필드를 가지고)의 왼쪽을 계산하기 위해 $ 프로젝트를 사용합니다. 그런 다음 일정 및 필터와 비교 $ 일치를 사용합니다. 이 방법 당신은 자바 스크립트를 실행하지 마십시오. 다음은 파이썬에서 내 테스트는 다음과 같습니다

    경우 성능은 가독성보다 더 중요하고 한 당신의 상태는 간단한 산술 연산으로 구성되어, 당신은 집계 파이프 라인을 사용할 수 있습니다. 첫째, 조건 (왼쪽에 모든 필드를 가지고)의 왼쪽을 계산하기 위해 $ 프로젝트를 사용합니다. 그런 다음 일정 및 필터와 비교 $ 일치를 사용합니다. 이 방법 당신은 자바 스크립트를 실행하지 마십시오. 다음은 파이썬에서 내 테스트는 다음과 같습니다

    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 MS

    발견 및 $ 사용 :

    %timeit -n1 -r1 list(coll.find({'$where': 'this.Grade1 > this.Grade2'}))
    

    1 개 루프, 1의 최고 : 루프 당 4.54의

  5. from https://stackoverflow.com/questions/4442453/mongodb-query-condition-on-comparing-2-fields by cc-by-sa and MIT license