중첩 된 객체를 쿼리하는 방법?


204

중첩 된 객체 표기법으로 mongoDB를 쿼리 할 때 문제가 있습니다.

db.messages.find( { headers : { From: "reservations@marriott.com" } } ).count()
0
db.messages.find( { 'headers.From': "reservations@marriott.com" }  ).count()
5

내가 뭘 잘못하고 있는지 알 수 없습니다. 중첩 된 객체 표기법이 점 표기법 쿼리와 동일한 결과를 반환 할 것으로 예상됩니다. 내가 어디 틀렸어?

답변:


419

db.messages.find( { headers : { From: "reservations@marriott.com" } } )

이것은 headers 등가 { From: ... } 인 문서 , 즉 다른 필드를 포함하지 않는 문서를 쿼리 합니다.


db.messages.find( { 'headers.From': "reservations@marriott.com" } )

headers.From포함되거나 누락 된 다른 필드의 영향을받지 않고 필드 만 확인 headers합니다.


점 표기법 문서


"headers.From"에 따옴표없이이 작업을 수행 할 수있는 방법이 있습니까?
trysis

나도 모르고 궁금해하며 때로는 유용 할 수 있다고 생각했습니다.
trysis

3
@trysis-실제로는 몽골 문서의 예제와 같은 인라인 객체를 선언하는 것만으로는 현실 세계에서 충분하지 않다는 것을 알았습니다. 나는 conditions['some.path'] = 'value'비즈니스 로직에서 와 같은 일을 할 수있는 '조건'과 '필드'객체를 생성하는 습관을 개발했다. 그리고 마지막에 단일 쿼리를 실행한다.find(conditions, fields, callback);
Ryan Wheale

"domain.com"이 포함 된 키가 있다고 가정하면 작동하지 않습니다 domains.domain.com. domain.com을 domain_com과 같은 것으로 바꾸지 않고이 시나리오에 대한 해결 방법이 있습니까?
Rens Tillmann

1
내 의견에 대답하면 키에 점을 완전히 사용하지 않는 것이 가장 좋습니다. 내 솔루션에서 키가되는 도메인을 완전히 버리고 대신 슬라이스 / 배열을 만들었습니다.
Rens Tillmann

20

두 개의 쿼리 메커니즘 은 하위 문서 섹션 의 문서 에서 제안한 것처럼 다른 방식으로 작동합니다 .

필드가 포함 된 문서 (즉, 보유하는 경우 하위 문서를 ), 당신도 전체 지정할 수 있습니다 하위 문서 은 "에 도달"는 필드의 값, 또는 하위 문서를 의 개별 필드에 대한 값을 지정하는 점 표기법을 사용하여 하위 문서를 :

하위 문서 내의 동일 항목 일치는 하위 문서가 필드 순서를 포함하여 지정된 하위 문서와 정확히 일치하는 경우 문서를 선택합니다.


다음 예제에서 쿼리는 필드 생산자 값이 값을 가진 필드 만 포함하는 하위 문서 인 모든 문서를 일치 company시킵니다.'ABC123' 하고 필드 address값으로 '123 Street'정확한 순서를 :

db.inventory.find( {
    producer: {
        company: 'ABC123',
        address: '123 Street'
    }
});

8
나는 미쳐 가고 있었다. 객체를 쿼리 할 때 직접 속성을 어떤 순서로도 일치시킬 수 있기 때문에 이것은 일관되지 않은 것처럼 보입니다.
Capaj

7

하위 문서로 MongoDB 수집 쿼리 에 대해 많은 혼란이 있기 때문에 위의 답변을 예제와 함께 설명하는 것이 .

먼저 컬렉션에 두 개의 객체 만 삽입했습니다 message.

> db.messages.find().pretty()
{
    "_id" : ObjectId("5cce8e417d2e7b3fe9c93c32"),
    "headers" : {
        "From" : "reservations@marriott.com"
    }
}
{
    "_id" : ObjectId("5cce8eb97d2e7b3fe9c93c33"),
    "headers" : {
        "From" : "reservations@marriott.com",
        "To" : "kprasad.iitd@gmail.com"
    }
}
>

따라서 쿼리 결과는 무엇입니까? db.messages.find({headers: {From: "reservations@marriott.com"} }).count()

이 값은 object 와 동일한 문서를 쿼리하므로 다른 필드 만 포함하지 않거나 전체 하위 문서를 필드 값으로 지정해야 하기 때문에 하나 여야합니다.headers{From: "reservations@marriott.com"}

그래서 @ Edmondo1984의 답변에 따라

하위 문서 내에서 동등 일치는 하위 문서 가 필드 순서를 포함하여 지정된 하위 문서와 정확히 일치 하는 경우 문서를 선택합니다 .

위의 진술에서 아래 쿼리 결과는 무엇입니까?

> db.messages.find({headers: {To: "kprasad.iitd@gmail.com", From: "reservations@marriott.com"}  }).count()
0

그리고 우리는의 순서를 변경 할 경우 FromTo두 번째 문서의 하위 문서로 같은 즉?

> db.messages.find({headers: {From: "reservations@marriott.com", To: "kprasad.iitd@gmail.com"}  }).count()
1

따라서 order 필드를 포함하여 지정된 하위 문서정확하게 일치 합니다 .

도트 연산자를 사용하면 모든 사람에게 매우 명확하다고 생각합니다. 아래 쿼리 결과를 보자.

> db.messages.find( { 'headers.From': "reservations@marriott.com" }  ).count()
2

위의 예제를 사용하여 이러한 설명을 통해 하위 문서로 찾기 쿼리를 보다 명확하게 수행 할 수 있기를 바랍니다 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.