연산자
여기서는 쿼리에서 사용 가능한 연산자를 설명합니다. 사용 가능한 연산자는 다음과 같습니다.
$lt
: 작은$le
: 작거나 같은$gt
: 큰$ge
: 크거나 같은$eq
: 같은$ne
: 같지 않은$in
: 포함하는$not_in
: 포함되지 않는$exists
: 존재하는$match
: 와일드카드 매칭$regex
: 정규식 매칭$and
: AND$or
: OR$nor
: NOR, Not OR$not
: NOT$project
: 열을 선택$limit
: 출력 항목의 수를 제한$skip
: 시작 위치를 정의$sort
: 정렬$unnest
: 계층적인 데이터를 1차원으로 변환$literal
: 특정한 값을 칼럼에 추가$group
: 통합$join
: 조인$union
: union 조인$hint
: 색인을 위한 힌트$search
: 전문 검색
비교: $lt
, $le
, $gt
, $ge
, $eq
, $ne
비교 연산자는 항목간 비교하거나 같거나 다른지를 판단합니다.
다음 예시는 key1
항목이 10보다 작은지를 검사합니다.
"key1": {
"$lt": 10
}
포함: $in
, $not_in
$in
과 $not_in
은 필드에 특정한 값들이 포함되는지 포함되지 않는지를 검사하는 연산자입니다.
다음 예시는 key1
항목에 1, 2, 5 중에 하나가 포함되어 있는지 검사합니다.
"key1": {
"$in": [1, 2, 5]
}
존재 여부: $exists
필드에 값이 존재하는지 확인합니다.
다음 예시는 key1
에 값이 존재 여부를 확인합니다.
"key1": {
"$exists": True
}
부분 일치: $match
와일드카드(wildcard)를 사용하여 일치 여부를 확인합니다.
다음 예시는 key1
에 search
로 시작하는 문자열이 있는지 확인합니다. $options
에 ignore-case
를 전달하면 대소문자 구별없이 확인할 수 있습니다.
"key1": {
"$match": "search*",
"$options": "ignore-case"
}
정규식 일치: $regex
정규식 (opens in a new tab)을 사용하여 일치 여부를 확인합니다.
다음은 key1
에 숫자가 포함된 문자열을 찾는 예시입니다.
"key1": {
"$regex": ".+\d+",
}
Boolean: $and
, $or
, $nor
, $not
불리언 연산자를 통해 조건을 조합하여 검색할 수 있습니다.
아래는 id
가 1, 2, 5 중에 하나이면서 title
이 search
가 일치하지 않는 데이터를 찾는 쿼리의 예시입니다.
"$and": [
{
"id": {
"$in": [1, 2, 5]
}
},
{
"$not": [
{
"title": {
"$match": "search*"
}
}
]
}
]
Project: $project
$project
는 칼럼을 선택하는 연산자 입니다.
다음 예시는 key1
, key2
를 선택하는 예시입니다.
"$project": ["key1", "key2"]
갯수 제한: $limit
$limit
는 연산된 결과값에서 선택할 행의 수를 제한하는 연산자입니다.
다음 예시는 10개의 행을 선택하는 예시입니다.
"$limit": 10
시작 위치: $skip
$skip
는 연산된 결과값에서 시작할 위치를 제한하는 연산자입니다.
다음 예시는 5번째 행부터 선택하는 예시입니다.
"$skip": 5
$skip
과 $limit
를 사용하여 pagenation을 구현할 수 있습니다.
정렬: $sort
$sort
는 연산된 결과값을 정렬하는 연산자입니다.
다음 예시는 key1
은 오름차순, key2
를 내림차순으로 결과값을 정렬하는 예시입니다. 나열된 순서를 우선하여 정렬됩니다.
"$sort": [
"key1",
{"key2": "desc"},
]
Flatten: $unnest
$unnest
는 지정된 칼럼의 데이터를 1차원 배열로 변환하는 연산자입니다.
예를 들어 다음과 같이 데이터가 있고
{
"_meta": {
"doc_id": 1
"score": 0.9
},
"title": "example 1"
}
이 데이터를 다음과 같이 쿼리하면
"$unnest": "_meta"
다음과 같이 변환됩니다.
[
"_meta.doc_id": 1,
"_meta.score": 0.9,
"title": "example 1"
]
값 지정: $literal
특정한 값을 칼럼에 추가합니다.
다음과 같은 데이터가 있을 때
data = [
{"doc_id": 1, "data": 1},
{"doc_id": 2, "data": 2},
{"doc_id": 3, "data": 3},
]
다음과 같이 실행하면
query = {
"$literal": {
"text": "test"
}
}
다음과 같은 결과를 얻을 수 있습니다.
doc_id data text
0 1 1 test
1 2 2 test
2 3 3 test
통합: $group
$group
쿼리된 결과값을 통합하여 재가공하는 연산자입니다.
여기서는 검색에서 사용하는 예시를 다시 사용하겠습니다. 우리는 6기통인 모델의 연도별 모델 수와 모델명, 해당연도 마력의 최대값을 구해보고자 합니다. 이 쿼리는 다음과 같이 작성할 수 있습니다.
query = [
{
"cylinders": 6,
},
{
"$group": {
"_id": "model_year",
"first_name": {
"$first": "name"
},
"horsepower_max": {
"$max": "horsepower"
},
"count": {
"$sum": 1
}
}
}
]
df = doc_db.find(collection_name, query)
print(df)
하나씩 살펴보면, $group
은 병합의 기준이 되는 칼럼인 _id
를 필수적으로 입력 받습니다. 이 경우 연도별 병합이기 때문에 model_year
를 선택했습니다.
"_id": "model_year"
다음 병합된 그룹에서 첫번째 모델의 name
을 가져옵니다. 여기서 first_name
은 $group
으로 만들어질 결과물 칼럼의 이름입니다.
"first_name": {
"$first": "name"
}
마지막 항목인 병합 결과물에 count
라는 칼럼을 신규로 만들고 "$sum": 1
하여 model_year
로 병합된 아이템들의 갯수를 계산합니다.
"count": {
"$sum": 1
}
실행 결과는 다음과 같습니다.
_id count first_name horsepower_max
0 70 4 plymouth duster 97.0
1 71 8 amc gremlin 110.0
2 73 8 plymouth valiant 122.0
3 74 7 plymouth duster 110.0
4 75 12 plymouth valiant custom 110.0
5 76 10 plymouth valiant 120.0
6 77 5 chevrolet concours 110.0
7 78 12 pontiac phoenix lj 165.0
8 79 6 pontiac lemans v6 115.0
9 80 2 dodge aspen 132.0
10 81 7 chevrolet citation 120.0
11 82 3 buick century limited 112.0
$group
의 연산자
병합에 사용할 수 있는 연산자는 다음과 같습니다.
$count
: 항목의 수$distinct_count
: 중복이 제외된 항목수$sum
: 합$mean
: 평균$variance
: 분산$stddev
: 표준편차$min
: 최대값$max
: 최소값$minmax
: 최대, 최소값$first
: 첫번째 항목$last
: 마지막 항목$array.push
: list로 변환$set.add
: set으로 변환$sketch.hll
: Sketchs의 HyperLogLog (opens in a new tab)를 사용하여 확률적으로 유일한 값의 수를 추정$sketch.kll
: Sketchs의 KllSketch (opens in a new tab)를 사용하여 분위수(quantile)를 계산$sketch.most_freq
: Sketchs의 Frequent Items (opens in a new tab)를 사용하여 고빈도 항목을 추정
Join: $join
, $union
두개의 컬렉션을 병합합니다.
test.join.left
와 test.join.right
를 생성하고 예제 데이터를 삽입하도록 하겠습니다.
from aeca import DocumentDB
doc_db = DocumentDB(channel)
collection_names = ["test.join.left", "test.join.right"]
indexes = [
{
"index_type": "kPrimaryKey",
"fields": ["doc_id"]
}
]
data = {
"test.join.left": [
{"doc_id": 1, "left": 1},
{"doc_id": 2, "left": 2},
{"doc_id": 3, "left": 3},
],
"test.join.right": [
{"doc_id": 1, "right": 1},
{"doc_id": 2, "right": 2},
{"doc_id": 5, "right": 5},
]
}
for name in collection_names:
doc_db.create_collection(name, indexes=indexes)
doc_db.insert(name, data[name])
$join
다음은 test.join.left
와 test.join.right
를 inner
join 하는 예시입니다.
query = {
"$join": {
"type": "inner",
"collection": "test.join.left",
"query": {},
"on": ["doc_id"]
}
}
df = doc_db.find("test.join.right", query)
print(df)
$join
에서 사용 가능한 옵션은 다음과 같습니다.
type
: 조인 방법inner
: 내부 조인, 기본값outer
: 외부 조인left
: left 조인right
: right 조인hash_inner
: 해시 내부 조인
collection
: 조인할 컬렉션query
: 조인할 컬렉션의 쿼리, 생략 가능on
: 조인할 키
위 예시의 실행 결과는 다음과 같습니다.
doc_id left right
0 1 1 1
1 2 2 2
$union
다음은 test.join.left
와 test.join.right
를 $union
하는 예시입니다.
query = {
"$union": {
"type": "all",
"collection": "test.join.left",
"query": {},
"on": ["doc_id"]
}
}
df = doc_db.find("test.join.right", query)
print(df)
$join
에서 사용 가능한 옵션은 다음과 같습니다.
- type: 조인 방법
- all: 전체
- distinct: 중복 제거
- collection: 조인할 컬렉션
- query: 조인할 컬렉션의 쿼리, 생략 가능
- on: 조인할 키
위 예시의 실행 결과는 다음과 같습니다.
doc_id left right
0 1 <NA> 1
1 2 <NA> 2
2 5 <NA> 5
3 1 1 <NA>
4 2 2 <NA>
5 3 3 <NA>
색인 힌트: $hint
색인을 위한 힌트를 제공합니다. 컬렉션에는 하나 이상의 색인이 저장될 수 있고 입력된 쿼리에 대해 쿼리 플래너는 이 색인들을 조합하여 최적의 색인을 선택합니다. 그러나 $hint
를 통해 색인이 선택되면 해당 색인을 우선적으로 사용합니다.
{
"$search": {
"query": "cat"
},
"$hint": "sk_fts"
}
전문 검색: $search
$search
는 전문 검색하는 연산자입니다.
다음은 검색 예시입니다.
"$search": {
"query": "content:(hello world)",
"fields": ["content"]
}
사용 가능한 옵션은 다음과 같습니다.
항목 | 설명 | 타입 | 기본값 |
---|---|---|---|
query | 검색 쿼리 쿼리 작성 방법은 전문 검색를 참고 | str | |
fields | 검색 대상 필드 | list[str] | 색인된 전체 필드 |
skip | 시작 위치 | int | |
limit | 후보수 | int | |
timeout | 만료 시간 | int | |
min_score | 최소 점수 | float | |
highlight | 하이라이트 | bool | |
default_operator | + : Must# : Filter | str | None: Should |