GeoJSON
JSON 형태로 지형 데이터를 정의하는 포맷.
GeoJSON의 타입에는
Point,LineString,Polygon,MultiPoint,MultiLineString,MultiPolygon,GeometryCollection이 있다.위 타입들에서 볼 수 있듯이, 좌표점 뿐만이 아니라 선에서 다각형, 여러 도형들까지 지원.
coordinates필드는type에 따라 여러 좌표점을 포함 할 수 있습니다.
점 - 경도, 위도의 좌표를 list에 넣는다. [경도, 위도]
{
"name": "Seoul",
"loc": {
"type": "Point",
"coordinates": [10, 1]
}
}
선 - 점을 이으면 선이 된다.
{
"name": "Busan",
"loc": {
"type": "LineString",
"coordinates": [[0,1], [0,2], [1,2]]
}
}
다각형 - 선과 비슷하게 배열로 만들지만 type 다름.
{
"name": "Busan",
"loc": {
"type": "Polygon",
"coordinates": [[0,1], [0,2], [1,2]]
}
}
db.Map.createIndex({"loc": "2dsphere"})
ㄴ 필드명에 따라 도형 설정하는 도큐먼트 필드가 지정된다.교차, 포함, 근접 유형있음
geoWithin특정 지역에 완전히 포함된 항목을 쿼리할 수 있다.
> db.Map.find({”loc”: “$geoWithin”: {”$geometry”: eastVillage}}})
near: 주변 위치 쿼리
> db.Map.find({"loc": {"$near": {"$geometry": esatvillage}}})
사용자가 현재 위치한 지역을 찾는다.
해당 지역 내 레스토랑 수를 보여준다.
지정된 거리 내에 있는 레스토랑을 찾는다.
2dsphere인덱스 사용
| 쿼리 유형 | 기하 구조 유형 |
|---|---|
| $near (GeoJSON point, 2dsphere 인덱스) | 구면 |
| $near (레거시 좌표, 2d 인덱스) | 평면 |
| $geoNear (GeoJSON point, 2dsphere 인덱스) | 구면 |
| $geonear (레거시 좌표, 2d 인덱스) | 평면 |
| $nearSphere (GeoJSON point, 2dsphere 인덱스) | 구면 |
| $nearSphere (레거시 좌표, 2d 인덱스) | 구면 |
| geoWithin {geometry} | 구면 |
| geoWithin {box} | 평면 |
| geoWithin {polygon} | 평면 |
| geoWithin {center} | 평면 |
| geoWithin {centerSphere} | 구면 |
| $geoIntersects | 구면 |
2d 인덱스는 구에서 평면과 거리 계산 지원.
구 형태 쿼리는 2dsphere로 성능, 정확성 올림
goeNear 연산자는 집계연산자
$near 쿼리 연산자는 mongoDB의 확장 솔루션인 샤딩을 사용해 배포된 컬렉션에서 작동X
geoNear 명령과 $geoNear 를 사용하려면 컬렉션에 2dsphere 인덱스와 2d 인덱스가 최대 1개만 존재해야 함
$near, $geoWithin 같은 공간 정보 쿼리 연산자는 컬렉션이 여러 개의 공간 정보 인덱스를 갖도록 허용된다.
$geoNear와 geoNear는 둘 다 위치 필드를 포함하지 않으므로 공간 정보 인덱스 제한이 존재
- tags 필드 추가
db.openStreetMap.createIndex({"tags": 1, "location": "2dsphere"})db.openStreetMap.find({"loc": {"$geoWithin":
{"$geometry": hellsKitchen.geometry}},
"tags": "pizza"})2dsphere 필드 앞, 뒤로 인덱스 필드를 추가 가능완전 평평한 표면이라 가정
평면형 지도 2d 인덱스 사용
db.hyrule.createIndex({"tile": "2d"})
구체에 2d 사용하지 말자
GeoJSON 데이터는 2d 사용에 적합하지 않다.
점만 인덱싱 가능. 점을 배열로 만들 순 있지만, 선은 아니다.
도로를 점으로 저장했을 때, $geoWithin 쿼리에서 점 하나만 인식해도 일치하게 반환된다.
default 인덱스 값: -180, 180
> db.hyrule.createIndex({"light-years": "2d"}, {"min": -1000, "max": 1000})
ex
사각형 내 도큐먼트 쿼리
db.hyrule.find({
tile: {
$geoWithin: {
$box: [[10, 10], [100, 100]]
}
}
})
중심이 [-17, 20.5]이고, 반지름이 25인 원 내에 있는 도큐먼트 쿼리
db.hyrule.find({
tile: {
$geoWithin: {
$center: [[-17, 20.5], 25]
}
}
})
다각형 도큐먼트 쿼리
db.hyrule.find({
tile: {
$geoWithin: {
$polygon: [[0, 0], [3, 6], [6, 0]]
}
}
}]
polygon(다각형)은 점의 배열로 저장.
배열의 마지막 점은 첫번 째 점에 이어짐.
// title과 body 필드 내 용어를 기반으로 인덱스 생성
db.articles.createIndex({"title": "text",
"body": "text"})> db.articles.createIndex({"title": "text",
"body": "text"},
{"weights": {
"title": 3,
"body": 2}}) $** 에 인덱스를 만들면 도큐먼트의 문자열 필드에 인덱스 생성 가능$text는 공백과 ., 구분 기호를 사용해 문자열 토큰화 하여, 검색 문자열에서 모든 토큰의 논리적 OR 을 수행한다.공백으로 impart , crater , lunar 단어가 포함된 title 필드에서 검색한다(OR).
db.articles.find({"$text": {"$search": "impart crater lunar"}},
{title: 1}).limit(10)
관련성이 없는 결과값이 포함될 수 있다.
impart , crater , lunar 를 OR를 사용해 쿼리를 실행한다 - 쿼리가 매우 광범위하다.
결과를 관련성에 따라 정렬하지 않는다.
// "impact crater" 구문이 포함된 도큐먼트를 찾는다.
// "impact crater" AND "lunar"로 처리
db.articles.find({$text: {$search: "\"impact crater\" lunar"}},
{title: 1}
).limit(10)
// "impact crater" AND ("lunar" OR "meteor")로 처리
db.articles.find({$text: {$search: "\"impact crater\" lunar meteor"}},
{title: 1}
).limit(10)
// "impact crater" AND ::lunar" AND "meteor"
db.articles.find({$text: {$search: "\"impct crater\" \"lunar\" \"meteor\""}},
{title: 1}
).limit(10)
.메타데이터 $meta 연산자를 사용해 textScore로 필드를 지정하여 메타 데이터 필드에 저장된다.
> db.articles.find({$text: {$saerch: "\" impact crater\" lunar"}},
{title:1, score: {$meata: "textScore"}}
).limit(10)
>> {"_id": "2", "title": Schjellerup (crater)", "score": 2.85298713914}
점수 순 결과 정렬 sort 호출
> db.articles.find({$text: {$saerch: "\" impact crater\" lunar"}},
{title:1, score: {$meata: "textScore"}}
).sort({score: {$meta: "textScore"}}).limit(10)
db.blog.createIndex({"date": 1, "post": "text"})언어에 따라 형태소가 달라 도큐먼트 언어 명시 필요
default: english
db.users.createIndex({"profil": "text",
"interets": "text"},
{"default_language": "french"})
도큐먼트 별로 language 설정 가능
db.users.insert({"username": "jaemoon", lnaguage: "swedish"})
와이어드타이거 스토리지 엔진에서 더 나은 성능 발휘 - 제한 컬렉션보다 권장됨10만 바이트 고정 크기로 제한 컬렉션 생성
db.createCollection("my_collection", {"capped": true, "size": 100000});
도큐먼트 100개로 제한하는게 아닌가??
db.createCollection("my_collection2", {"capped": true, "size": 10000, "max": 100});
1만 바이트 크기의 제한 컬렉션 변환 코드
db.runCommand({"convertToCapped": "test", "size": 10000}), {"ok": true}
// expireAfterSecounds 초를 지나면 도큐먼트 삭제
db.sessions.createIndex({"lastUpdated": 1}. {"expireAfterSecounds": 60*60*24})// runCommand로 expireAfterSecounds 수정 가능
db.runCommand({"collMod": "someapp.cache",
"index":
{"keyPattern": {"lastUpdated":1}, "expireAfterSeconds": 3600}})