DB/MongoDB

[MongoDB] 쿼리

프흐프좋아 2024. 2. 26. 23:53

find

db.c.find()

 

- 여러개를 추가하면 AND 조건으로 해석된다

db.c.find({"user" : "Joe", "age" : 23})

 

반환받을 키 지정

db.c.find({},{"user" : 1, "age" : 1})

 

- find를 통해 특정한 값만 select하고 싶은 경우 {} 뒤에 매개변수에 원하는 키를 지정하면 된다

- _id는 지정하지 않아도 항상 반환되는데

db.c.find({},{"user" : 1, "_id" : 0})

 

위에 처럼 0 으로 설정해서 뽑으면 제외할 수 있다

 

제약 사항

- 쿼리에는 몇가지 제약이 있는데, 그 중 하나는 데이터베이스에서 쿼리 도큐먼트 값은 반드시 상수(변하지 않는 수)여야 한다

- 아래 예시는 작동하지 않는다

db.c.find({"user" : "this.num_old" })

 

쿼리 조건

- < <= > >= 에 해당하는 비교 연산자는 $lt $lte $gt $gte다

- 예를 들어 18세와 30세 사이의 사용자를 찾으려면 다음과 같이 쿼리한다

db.c.find({"age" : {$gte : 18 , $lte : 30} })

 

- 키 값이 특정 값과 일치하지 않는 도큐먼트를 찾는 데는 "not equal"을 나타내는 "$ne"를 사용한다.

- 예를 들어 사용자명이 "joe"가 아닌 사용자를 모두 찾으려면 다음과 같이 쿼리한다

db.c.find({"name" : {$ne : "Joe"})

 

OR 쿼리

- 몽고에서 OR쿼리는 두가지 방법 정도 있다

- $in 과 $or 가 있다.

- $in은 하나의 키를 다양한 값과 비교하는 쿼리에 사용하고

- $or은 여러 키를 주어진 값과 비교하는 쿼리에 사용한다

db.c.find({"name" : {$in : ["Joe","John","Lim"]}})
db.c.find({$or : [{"ticket_no" : 725},{"winner" : true}]})

 

쿼리 옵티마이저는 $in을 좀 더 효율적으로 다룬다.

 

$not

- $not은 메타 조건절이며 어떤 조건에도 적용할 수 있다

- $not은 정규 표현식과 함께 사용해 주어진 패턴과 일치하지 않는 도큐먼트를 찾을 때 특히 유용하다.

 

null

- null은 스스로와 일치하는 것을 찾는다.

- 예를 들어 "y" 키가 null인 도큐먼트를 찾는다면,

"y"의 키 값이 null인 도큐먼트를 출력하겠지만, "y"라는 키 값이 존재하지 않는 도큐먼트 또한 반환한다.

- 값이 null인 키만 찾고싶다면, $exists조건절을 사용해서 true로 키면 "y" 키 값이 null 값인 경우만 리턴한다.

 

$all 연산자

- 2개 이상의 배열 요소가 일치하는 배열을 찾으려면 $all을 사용한다

- 순서는 중요하지 않고, 존재 유무만 판별한다

 

배열 및 범위 쿼리의 상호작용

- 범위 쿼리를 쓰는건.. 은근 히 구리다..

5, 15, 20, [5,25]가 있는 상황에서

$gt : 10, $lt : 20을 쓴다면 15값만을 받을 것 같지만

15랑 [5,25] 두개가 같이 리턴된다.

 

따라서 이 방법을 사용하면 배열에 대한 범위 쿼리가 본질적으로 쓸모없어진다.

범위가 모든 다중 요소 배열과 일치하기 때문이다. ($lt $gt 구리니까 쓰지마라..)

 

대신 $eleMatch : { "$gt" : 10, "$lt" : 20} 를 쓴다면 원하는 값을 얻을 수.. 있다고는 하는데 못얻는다

$eleMatch는 비배열 요소를 일치시키지 않는다는 함정이 있다!(도대체 뭘 쓰면..)

그래도 배열 요소에 대해서는 범위 쿼리가 용하다.

 

쿼리하는 필드에 인덱스가 있다면 $max $min을 사용하면 좋다

 

내장 도큐먼트에 쿼리하기

db.c.find({"name" : {"first" : "Joe", "last" : "Schome" }})

 

대신 아래처럼 써서 검색하는게 좋다. 만약 쿼리하는 도중 first와 last 키 값 사이에 middle 같이 새로운 키값이 insert가 되는경우 find는 정확히 순서까지 동일한 데이터만 찾기 때문에 상단의 리턴값은 아무것도 나오지 않는다.

db.c.find({"name.first" : "Joe", :"name.last" : "Schome" })