codememo

MongoDB 쿼리 도움말 - 하위 개체에 있는 키 값에 대한 쿼리

tipmemo 2023. 5. 8. 22:15
반응형

MongoDB 쿼리 도움말 - 하위 개체에 있는 키 값에 대한 쿼리

이 컬렉션에 대해 쿼리를 수행하여 특정 값과 일치하는 항목에 키가 있는 문서를 확인합니다.이것이 가능합니까?

다음과 같은 문서 모음이 있습니다.

{
    "things": {
        "thing1": "red",
        "thing2": "blue",
        "thing3": "green"
    }
}

편집: 간결함을 위해

키가 무엇인지 모르고 대화형이어야 하는 경우 다음과 같은 (성능 문제가 있는) 연산자를 사용해야 합니다(셸에서).

db.test.find({$where: function() { 
    for (var field in this.settings) { 
        if (this.settings[field] == "red") return true;
    }
    return false;
}})

컬렉션이 많은 경우 사용자의 목적에 비해 너무 느릴 수 있지만 키 집합을 알 수 없는 경우에는 이 방법이 유일한 옵션입니다.

MongoDB 3.6 업데이트

이제 이 작업을 수행할 수 있습니다.$where집계 연산자 사용:

db.test.aggregate([
  // Project things as a key/value array, along with the original doc
  {$project: {
    array: {$objectToArray: '$things'},
    doc: '$$ROOT'
  }},

  // Match the docs with a field value of 'red'
  {$match: {'array.v': 'red'}},

  // Re-project the original doc
  {$replaceRoot: {newRoot: '$doc'}}
])

MongoDB에서 실제로 합리적인 쿼리를 할 수 있도록 스키마 변경을 제안합니다.

시작:

{
    "userId": "12347",
    "settings": {
        "SettingA": "blue",
        "SettingB": "blue",
        "SettingC": "green"
    }
}

대상:

{
    "userId": "12347",
    "settings": [
        { name: "SettingA", value: "blue" },
        { name: "SettingB", value: "blue" },
        { name: "SettingC", value: "green" }
    ]    
}

그러면 인덱스를 작성할 수 있습니다."settings.value"다음과 같은 쿼리를 수행합니다.

db.settings.ensureIndex({ "settings.value" : 1})

db.settings.find({ "settings.value" : "blue" })

설정 이름과 설정 값을 완전히 인덱싱 가능한 필드로 이동하고 설정 목록을 배열로 저장하기 때문에 변경 작업은 간단합니다.

스키마를 변경할 수 없다면 @Johnny를 시도해 볼 수 있습니다.HK해결책이지만 기본적으로 성능 면에서 최악의 경우이며 지수로는 효과적으로 작동하지 않을 것이라는 점을 경고합니다.

안타깝게도, 이전의 답변 중 어떤 것도 mongo가 배열 또는 중첩된 개체에 내포된 값을 포함할 수 있다는 사실을 다루지 않았습니다.

다음은 올바른 질문입니다.

{$where: function() {
    var deepIterate = function  (obj, value) {
        for (var field in obj) {
            if (obj[field] == value){
                return true;
            }
            var found = false;
            if ( typeof obj[field] === 'object') {
                found = deepIterate(obj[field], value)
                if (found) { return true; }
            }
        }
        return false;
    };
    return deepIterate(this, "573c79aef4ef4b9a9523028f")
}}

배열 또는 중첩된 개체에서 유형을 호출하면 'object'가 반환되므로 쿼리가 모든 중첩된 요소에서 반복되고 값이 있는 키를 찾을 때까지 모든 요소를 반복합니다.

값이 내포된 이전 답변을 확인할 수 있으며 결과는 원하는 것과 거리가 멀어집니다.

전체 개체를 문자열로 묶는 것은 모든 메모리 섹터를 하나씩 반복하여 일치시켜야 하기 때문에 성능에 큰 영향을 미칩니다.그리고 객체의 복사본을 램 메모리에 문자열로 만듭니다(쿼리가 더 많은 램을 사용하기 때문에 비효율적이고 함수 컨텍스트에 이미 로드된 객체가 있기 때문에 느립니다).

쿼리 자체는 objectId, string, int 및 원하는 기본 자바스크립트 유형과 함께 작동할 수 있습니다.

언급URL : https://stackoverflow.com/questions/19802502/mongodb-query-help-query-on-values-of-any-key-in-a-sub-object

반응형