MongoDB에서 2단계(two-level) 깊이에 위치한 레코드를 조회하려면 $where 연산자 내부에 반복문을 작성하면 됩니다. 이 방법은 문서의 최상위 필드들을 순회하면서 각 필드의 하위 문서(중첩된 객체) 안에서 원하는 조건을 만족하는 값을 찾는 방식입니다.
샘플 컬렉션 생성하기
먼저 데모용 컬렉션을 생성하고 문서를 삽입해 보겠습니다.
> db.demo468.insertOne(
... {
... "_id" : new ObjectId(),
... "FirstPosition" : {
... "StudentName" : "Chris",
... "StudentAge" : 23
... },
... "SecondPosition" : {
... "StudentName" : "David",
... "StudentAge" : 20
... }
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e804e2fb0f3fa88e2279069")
}
> db.demo468.insertOne(
... {
... "_id" : new ObjectId(),
... "FirstPosition" : {
... "StudentName" : "Carol",
... "StudentAge" : 21
... },
... "SecondPosition" : {
... "StudentName" : "John",
... "StudentAge" : 22
... }
... }
... );
{
"acknowledged" : true,
"insertedId" : ObjectId("5e804fb0b0f3fa88e227906a")
}컬렉션의 모든 문서 확인하기
find() 메서드를 사용하면 컬렉션에 저장된 모든 문서를 화면에 출력할 수 있습니다.
> db.demo468.find();
위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : ObjectId("5e804e2fb0f3fa88e2279069"), "FirstPosition" : { "StudentName" : "Chris",
"StudentAge" : 23 }, "SecondPosition" : { "StudentName" : "David", "StudentAge" : 20 } }
{ "_id" : ObjectId("5e804fb0b0f3fa88e227906a"), "FirstPosition" : { "StudentName" : "Carol",
"StudentAge" : 21 }, "SecondPosition" : { "StudentName" : "John", "StudentAge" : 22 } }2단계 깊이의 레코드 조회 쿼리
다음은 $where와 JavaScript 반복문을 활용하여 2단계 깊이의 레코드를 조회하는 쿼리입니다. 각 문서의 모든 최상위 필드를 순회하면서 하위 문서의 StudentName 값이 "John"인 경우 해당 문서를 반환합니다.
> db.demo468.find({
... $where: function() {
... for (var i in this) {
... if (this[i]["StudentName"] == "John") {
... return true;
... }
... }
... return false;
... }
... })위 쿼리를 실행하면 다음과 같은 결과가 출력됩니다.
{ "_id" : ObjectId("5e804fb0b0f3fa88e227906a"), "FirstPosition" : { "StudentName" : "Carol",
"StudentAge" : 21 }, "SecondPosition" : { "StudentName" : "John", "StudentAge" : 22 } }참고 사항
$where는 JavaScript 코드를 서버에서 실행하기 때문에 유연하지만, 인덱스를 활용할 수 없어 성능이 떨어질 수 있습니다. 따라서 실제 운영 환경에서는 가능한 한 점 표기법(dot notation)을 사용한 일반 쿼리(예: { "FirstPosition.StudentName": "John", $or: [{ "SecondPosition.StudentName": "John" }] })를 우선적으로 고려하고, 필드 이름이 동적이거나 구조가 고정되지 않은 경우에만 $where를 사용하는 것이 좋습니다.