Document에 너무 많은 필드와 정보가 있을 때 정보를 확인하기 어려울 때가 있습니다.
이를 완화하기 위해 find 쿼리에 프로젝션을 추가해 현재 관심있는 필드만 결과로 가져올 수 있습니다.
데이터베이스에서 조건에 해당하는 Document를 찾고 특정 필드만 결과에 포함하는 쿼리입니다.
ex) address와 price필드만 결과로 가져올 수 있도록
ds.컬렉션이름.find({"amenities": {"$size":20, "$all": ["Internet", "Wifi", "Heating",...]}}, {"price": 1, "address": 1}).pretty()
// 두 번째 인자를 통해서 price와 address만 가져올 수 있습니다.
find쿼리의 첫 번째 인자에서 찾으려는 Document 조건이 옵니다. 두 번째 인자로 우리가 찾고 있는 필드를 구체적으로 설명하는 projection입니다.
프로젝션을 사용할 때, 0 과 1을 사용해 결과에서 표시하거나 표시하지 않을 필드를 지정할 수 있습니다.
1을 사용하는 경우 지정한 필드와 _id 필드만 가져옵니다.
0을 사용하는 경우 지정한 필드를 제외한 모든 필드가 표시됩니다.
주의사항: 한 번의 프로젝션에서 0과 1을 혼합할 수 없습니다.
db.컬렉션이름.find({query}, {projection})
ex) 85점 이상의 성적을 받고, 431 수업을 듣는 학생을 찾아보자.
db.grades.findOne()
// 아래는 출력 결과
{
...
...
"scores":[
{
"type": "exam",
"score": "21"
},
{
"type": "quiz",
"score": "58"
},
{
"type": "homework",
"score": "83"
},
{
"type": "homework",
"score": "90"
},
],
"class_id": 265
}
우선 grades Collection의 Document를 찾아보자.
scores 필드는 배열임을 알 수 있습니다.
type필드보다 score 필드에 관심을 가져야한다.
scores 내 score 필드에 접근하기 위해서는 elemMatch를 사용하면됩니다.
db.grades.find({"class_id":431}, "scores":{"$elemMatch":{"score":{"$gt":85}}});
풀어서 해석하자면 grades collection에서 class_id 431을 찾고, $elemMatch를 통해서 지정한 배열 필드가 Document에 존재하고 조건에 맞는 요소가 있는 경우 해당 필드를 결과에 포함시킵니다.
score는 scores 배열 필드 안에 존재하기 때문에 $elemMatch를 통해서 원하는 결과를 출력받을 수 있습니다.
db.grades.find({"scores":{"$elemMatch":{"type":"extra credit"}}}).pretty();
위 명령어는 grades Collection에서 scores 필드 내 타입이 "extra credit"인 학생을 찾는 명령어 입니다.
scores 배열 내 type 필드를 가지고 type이 "extra credit"인 학생을 찾는 것입니다.
db.collection.find({query}, {projection});
projection에서 0과 1을 사용하여 특정 필드를 포함 또는 제외할 수 있습니다.
0과 1은 혼용해서 사용할 수 없습니다.
{field:{"$elemMatch":{filed:value}}}
첫 번째 인자에서 쓰일 경우, 배열 필드의 서브 Document 필드가 쿼리와 일치하는 문서를 찾습니다.
두 번째 인자에서 쓰일 경우, 지정된 기준과 일치하는 요소가 하나 이상있는 배열 요소만 프로젝션 합니다.
MongoDB에서는 유연한 데이터 모델링을 통해 개발자가 데이터를 저장할 방법을 결정할 수 있습니다.
일반적으로 서브 Document 또는 배열로 저장합니다.
ex) 예시
db.trips.findOne();
// 아래는 trips Collection에 대한 결과물
{
...
...
...
...
...
"start station location":{
"type":"Point",
"coordinate": [
-73,
40
]
},
"end station location":{
"type":"Point",
"coordinate":[
-73,
40
]
}
}
trips Collection 내에는 start station location, end station location 등 다양한 필드가 존재하고 start station location, end station location 안쪽에는 Sub Document가 있습니다.
db.trips.findOne({"start station location.type": "Point"});
Dot Notation을 사용해 start station location.type:"Point" 에 접근할 수 있습니다.
db.collection 을 보면 데이터베이스 역시 collection으로 이동 시 Dot Notation을 사용하는 걸 알 수 있습니다.
따라서 Document가 있는 필드로 이동할 때도 점 표기법(Dot Notation)을 사용해 필드의 값을 가져올 수 있습니다.
ex) Sub Document 예제
db.companies.find({"relationship.person.last_name": "Lee"}, {"name": 1}).pretty();
companies Collection 내에서 relationship 접근 relationship 내 person.last_name 필드로 진입한다. 이때 "Lee"라는 사람을 결과로 뽑아낼 수 있다.
ex) relationship 배열에서 first_name이 Mark, title이 CEO를 찾는다면?
db.companies.find({"relationship.person.first_name": "Mark", {"relationship.title": {"$regex": "CEO"}}, {"name": 1}).pretty();
$regex를 통해서 일치한 문자열을 지정할 수 있습니다.
ex) relationship 배열에서 회사를 떠난 사람 중 이름이 Mark인 사람을 찾는다면?
{"is_past": true},
{"person.first_name": "Mark"]
두 개의 조건을 만족해야 합니다.
db.companies.find({"relationship": {"$elemMatch": {"is_past": true, "person.first_name": "Mark"}}}, {"name": 1}).pretty();
$elemMatch를 통해 모든 배열 요소를 살펴보고 조건과 일치하는지 알 수 있습니다.
MQL에서 Dot notation을 사용하여 Sub Document 요소를 참조할 수 있습니다.
배열에서 Dot notation을 사용하려면 요소의 위치를 지정해야 합니다.
기본 문법(Syntax)
db.collection.find({"field1.other.anotherField": "value"});