16. MongoDB Query Part 6. - $where
이번 포스팅에서는 $where
key를 이용한 검색에 대해 알아보도록 하겠습니다.
$where
는 JavaScript의 표현식 또는 JavaScript 함수 전체를 query에 전달할 수 있는 오퍼레이터입니다.
설명을 위해 우선 다음 데이터를 준비하도록 하겠습니다:
db.grade.insert({student_id : "01", korean : "A", english: "B", maths : "A+", science : "A" })
db.grade.insert({student_id : "02", korean : "B", english: "B", maths : "A+", science : "B" })
db.grade.insert({student_id : "03", korean : "C", english: "A+", maths : "A+", science : "A" })
위에 입력된 데이터를 살펴보면 다음과 같습니다:
> db.grade.find().pretty()
{
"_id" : ObjectId("52efaab7614cff87320cc801"),
"student_id" : "01",
"korean" : "A",
"english" : "B",
"maths" : "A+",
"science" : "A"
}
{
"_id" : ObjectId("52efaab7614cff87320cc802"),
"student_id" : "02",
"korean" : "B",
"english" : "B",
"maths" : "A+",
"science" : "B"
}
{
"_id" : ObjectId("52efaab8614cff87320cc803"),
"student_id" : "03",
"korean" : "C",
"english" : "A+",
"maths" : "A+",
"science" : "A"
}
참고로, find()
명령에 뒤에 있는 pretty()
는 검색된 도큐먼트 내용을 잘 정리해서 보여주는 메써드입니다.
$where
key를 이용하여 국어(korean)와 과학(science) 등급이 같은 학생을 추출해 보겠습니다:
> db.grade.find({ $where: function() { return (this.korean == this.science) }}).pretty();
{
"_id" : ObjectId("52efaab7614cff87320cc801"),
"student_id" : "01",
"korean" : "A",
"english" : "B",
"maths" : "A+",
"science" : "A"
}
{
"_id" : ObjectId("52efaab7614cff87320cc802"),
"student_id" : "02",
"korean" : "B",
"english" : "B",
"maths" : "A+",
"science" : "B"
}
국어와 과학 등급이 같은 학생의 ID는 "01"과 "02"입니다.
이와 같이 $where
는 JavaScript 함수를 사용하여 query의 확장이 가능하게 합니다.
this
키워드가 사용되었음에 유의하시기 바랍니다.
유사하게, 이번에는 영어(english)와 수학(maths) 등급이 같은 학생을 추출하려면 다음과 같이 입력합니다:
> db.grade.find({ $where: function() { return (this.english == this.maths) }}).pretty();
{
"_id" : ObjectId("52efaab8614cff87320cc803"),
"student_id" : "03",
"korean" : "C",
"english" : "A+",
"maths" : "A+",
"science" : "A"
}
영어와 수학 등급이 같은 ID "03"의 학생이 검색되었음을 확인할 수 있습니다.
this
대신 obj
를 사용해도 동일한 결과를 얻을 수 있습니다:
> db.grade.find({ $where: function() { return (obj.english == obj.maths) }}).pretty();
{
"_id" : ObjectId("52efaab8614cff87320cc803"),
"student_id" : "03",
"korean" : "C",
"english" : "A+",
"maths" : "A+",
"science" : "A"
}
함수 형태로 표현된 위의 표현은 보다 간단하게 다음과 같이 표현할 수 있으며, 결과는 동일합다.
> db.grade.find( { $where: "obj.english == obj.maths" } ).pretty();
{
"_id" : ObjectId("52efaab8614cff87320cc803"),
"student_id" : "03",
"korean" : "C",
"english" : "A+",
"maths" : "A+",
"science" : "A"
}
MongoDB의 정규 오퍼레이터로는 처리할 수 없는 것도 이를 사용해 처리가 가능하므로 확장 측면에서는 매우 유용하나, 동일한 데이터 처리를 하는 정규 오퍼레이터가 존재한다면 가급적 쓰지 않도록 합니다.
즉, 정말로 꼭 필요한 상황이 아니면 절대 써서는 안 됩니다.
왜냐하면, 정규 오퍼레이터보다 처리속도가 현저히 떨어지기 때문입니다.