[MongDB]MongoDB 강의 내용 정리

MongoDB



개념

  • Mongo DB 는 NoSQL이다.
  • NoSQL의 특징
    • 고정되지 않은 스키마
      • 필요할 때 필드를 추가하고 제거할 수 있어 개발 속도를 향상시켜준다.
    • 데이터 간의 관계를 정의하지 않는 데이터베이스
      • db -> collection -> document
    • 분산형 구조(대용량 데이터 저장에 용이하다.)
      • sharding을 지원한다.(클러스터 데이터 상호 복제)


설치 및 환경 세팅

  • 몽고DB를 설치해보자
  • 구글에서 검색시 밑에껄로 접속
    • image
  • 학생이기 때문에.. CE 버전으로 다운을 받장
    • image
  • 그러면 pc 사양에 맞게 알아서 다운로드할 것을 잡아준다. 다운로드를 해주자.
    • image
  • 인스톨러에서 무작정 [Next]를 하지 않고, 설정을 하면서 넘어가자
  • 쭉 가다가 complete를 고르고
    • image
  • 경로 설정 을 지나서
    • image
  • 여기가 중요하다. Compass를 같이 받으면 설치가 터지는 경우가 많다고 한다. 해제하고 넘어가자.
    • image
  • 그리고 설치를 하고 완료가 된당
    • image
  • 내 컴퓨터 - [설정] - [고급시스템설정] - [환경 변수] - [Path] - [편집]
    • image
  • MongoDB bin 폴더경로를 복사
    • image
  • 환경변수에 경로 추가 후 확인
    • image
  • 명령프롬프트(CMD) 를 켜서 mongo를 쳐서 > 꺾쇠가 나오면 설치 완료
    • image


Shell

  • interactive javascript interface
    • 자바스크립트 기반
    • 자바스크립트 인터프리터를 사용
    • js program, library, functino 활용 가능
  • mongo에서 사용하는 js function은 console.log 대신 print를 사용
    • image
  • use라는 명령어로 DB를 변경할 수 있다.
    • image
  • show dbs
    • 데이터베이스명 및 공간확인
    • image
  • show collections
    • 해당 DB안에 있는 collection들을 출력
  • db
    • 현재 내가 사용하고 있는 데이터베이스명이 출력된다.


Structure

  • MongoDB의 구조
    • 데이터베이스(DB)
      • 콜렉션(Collection)
        • 문서(Document)
  • DataBase
    • 독립적인 하나의 권한
    • 각 db는 분리된 파일로 저장
  • colletion
    • document들의 group(rdbms - table)
    • 스키마를 가지지 않음 (document들의 필드가 각각 다름)
  • document
    • {field: value} 형태
    • data record를 BSON(Binary JSON)으로 저장
    • Filed(Key) 중복 불가


CRUD

  • 몽고 DB의 CRUD는 다음과 같이 4가지로 정의
    • insert
    • find
    • update
    • delete

(1) Insert

  • 사용 형태
    • 도큐먼트 하나 삽입할 때
      • db.collection.insertOne(document)
    • 도큐먼트 여러 개 삽입할 때
      • db.collection.insertMany([document,document])
  • _id : 주요키(Primary key)와 같은 개념으로 명시하지 않으면 자동으로 ObjectId가 생성된다.

  • DB의 jstest라는 콜렉션에 값을 넣고 확인해보자.

    • db.jstest.insertOne({name:'test', age:100, class:'de'})
    • db.jstest.insertOne({name:'mongo', class:'db'})
    • db.jstest.find()
    • image
  • insert하면 콜렉션을 생성치 않아도 자동으로 콜렉션이 생긴다

    • show collections
    • image
  • 자바스크립트 명령어로 변수를 만들어서 값을 넣어줄 수도 있음

    • mutli라는 콜렉션에 값들 입력

    • 한 개 삽입할 경우

      • var lee = {name:'lee-ss', midterm:{kor:70, eng:100}, final : {kor:100, eng:90, math:20, sci:50}, class:'de'}
        db.multi.insertOne(lee)
        
      • image
    • 여러 값 삽입할 경우

      • db.multi.insertMany(
        	[
        		{name:'kim-sd', class:'ds', kor:100, eng:40, math: 100},
        		{name:'kang-hd', class:'ds', kor:88, eng:50, math:70}
        	])
        
      • image

(2) find

  • RDBMS의 SELECT라고 생각하면 될듯

  • db.collection.find(query, projection)

    • query : 선택자
      • {<filed>: {<opr>:<value>}}
    • projection : 출력할 필드 선택
  • cursor

    • var cursor = db.collection.find()
    • find의 결과를 cursor에 저장한다.
    • hasNext(), forEach(), toArray().. 등등
    • 사용하면 소모된다.
  • 위에서 multi 에 입력했던 값들을 조회해보자.

    • 커서 사용

      • var cursor = db.multi.find()
        cursor
        
      • image

      • 여기서 다시 cursor를 호출하면, 아무 것도 나오지 않음. 즉, 1회성이다.

      • image
    • 커서를 사용치 않고도 조회할 수 있다.

      • db.multi.find()
        db.multi.find({})
        
      • image
    • projection 사용

      • db.multi.find({},{name:1})
        db.multi.find({},{_id:0,name:1})
        db.multi.find({},{_id:0,name:true,midterm:1})
        
      • image

      • db.multi.find({class:'de'})
        db.multi.find({class:'ds'})
        
      • image

      • db.multi.find({'midterm.kor':{$gt:50}})
        
      • $gt는 grater than을 뜻한다. 따라서 중간고사에서 국어 성적이 50과 같거나 큰 것들을 조회하라는 의미다.

      • image
    • 국어 점수가 존재하는 도큐먼트를 출력해보자

      • db.multi.find({kor: {$exists:true}})
        db.multi.find({'midterm.kor': {$exists:true}})
        
      • $exists:true는 해당 문서가 존재하는지 확인할 수 있는지 확인하는 명령어
    • 국어점수가 50점보다 크고, 100점보다 작은 도큐먼트 조회

      • $and 사용

      • db.multi.find({$and:[{kor:{$gt:50}},{kor:{$lt:100}}]})
        
      • 하나의 도큐먼트에서 조건 명시

      • db.multi.find({kor:{$gt:50}, kor:{$lt:100}})
        
      • image
  • 정렬하기

    • 1은 ASC, -1은 DESC

    • 형태 : db.collection.find().sort()

    • name을 기준으로 오름차순으로 정렬

      • db.multi.find().sort({name:1})
        
  • 제한해서 출력하기

    • 형태 : db.collection.find().limit()
  • 이쁘게(정렬해서) 출력하기

    • db.collection.find().pretty()
    • 몽고DB에서 자체적으로 알아서 이쁘게 출력시켜준다.

(3) update

  • 참고 : https://docs.mongodb.com/manual/crud/#update-operations

  • 사용 형태

    • 하나의 필드만 수정할 때
      • db.collection.updateOne(filter, update, options)
    • 여러 개의 필드를 수정할 때
      • db.collection.updateMany(filter, update, options)
    • document 자체를 수정할 때
      • db.collection.replaceOne(filter, update, options)
  • 파라미터

    • filter : 수정할 document를 찾는다.(find)
    • update : 수정될 내용
      • $set
      • 연산자 업데이트, 집계 파이프라인(update operator or aggregation pipeline)
    • options : upsert, writeConcern,.. 등 다양한 옵션들을 명시
  • name에 jeon이라는 값이 들어가는 문서를 찾아서 전동준으로 바꿔주자.

    • db.multi.updateOne({name:/jeon/},{$set:{name:'전동준'}})
      db.multi.find({},{_id:0, name:1})
      
    • image
  • 중간고사(midterm) 점수가 있는 모든 학생들의 class를 ‘graduated’로 바꾸자.

    • db.multi.updateMany({midterm: {$exists:true}},{$set: {class:'graduated'}})
      
    • image
  • 기말고사(final) 점수가 있는 모든 학생들의 class를 ‘job’로 바꾸자.

    • db.multi.update({final: {$exists:true}}, {$set:{class:'job'}})
      
  • 기말고사(final) 점수가 있는 도큐먼트 자체를 수정하자

    • db.multi.replaceOne({final:{$exists:true}},{class:'job'})
      
    • image

    • 도큐먼트 자체가 변경된 것을 확인할 수 있다.
  • 국어점수가 60점보다 적거나 같은 도큐먼트들을 찾아서, 국어 점수를 0점으로 만드는 자바스크립트 함수를 만들어 보시오. 함수 이름은 updateKor()으로 만들고, 업데이트 된 결과를 리턴하시오.

    • function updateKor(){
      	var tmp = db.multi.updateMany({kor:{$lte:60}},{$set:{kor:0}})
      	return tmp
      }
      updateKor()
      db.multi.find()
      
    • image

    • image

    • 60점보다 적은 도큐먼트가 없어서 변경된게 없는 것을 확인할 수 있다.

(4) delete

  • 사용 형태

    • 하나만 삭제할 때
      • db.collection.deleteOne(filter, options)
    • 여러 개를 삭제할 때
      • db.collection.deleteMany(filter, options)
  • 파라미터

    • filter : 삭제할 document를 선택(find)
    • options : collation, writeConcern 등 다양한 옵션 명시
  • name이 ‘전동준’ 인 도큐먼트 하나만 삭제하자.

    • db.multi.deleteOne({name:'전동준'})
      
    • image
  • class field가 존재하는 도큐먼드들을 모두 삭제하자.

    • db.multi.deleteMany({class:{$exists:true}})
      
    • image

연습문제

db.myfriends.insertOne({name:'아이언맨', buddy:['토르','헐크','호크아이']})
db.myfriends.insertOne({name:'슈퍼맨', buddy:['배트맨','원더우먼','아쿠아맨','조커']})
  • updateOne을 사용해, 아이언맨의 친구(buddy)에 캡틴아메리카, 블랙위도우를 추가하자.

    • update Operator를 찾아서 사용해야한다.

    • $push$each 사용

    • db.myfriends.updateOne(
      	{name:'아이언맨'},
      	{$push:{buddy:{$each:['캡틴아메리카','블랙위도우']}}}
      )
      
    • image
  • updateOne을 사용해, 슈퍼맨의 친구 중 가장뒤에 있는 친구(조커)를 빼주자.

    • $pop을 사용

    • db.myfriends.updateOne({name:'슈퍼맨'},{$pop:{buddy:1}})
      
    • image

    • 조커가 빠진 것을 확인할 수 있다.


Aggregation

  • Pipe Line : 이전 단계의 결과를 다음 단계의 입력으로 사용
  • Collection이 각 단계를 거치면서 document를 처리 및 집계
  • 일부 처리는 shard에 대응되어 각 shard에서 처리한다.
  • 형식 예
  • SQL 언어와 비교
    • WHERE = $match
    • HAVING = $match
    • GROUP BY = $group
    • SELECT = $project
    • ORDER BY = $sort
    • LIMIT = $limit
    • SUM = $sum
    • COUNT = $sum
  • 스테이지의 순서에 따라서 결과가 달라질 수 있다.

예제

  • 예제 데이터1

    • db.multi.insertMany(
      	[
      		{name:'hong-gd', kor:100, eng:30, math:60},
      		{name:'kim-sd', kor:40, eng:70, math:100},
      		{name:'park-jy', kor:100, eng:100, math:100},
      		{name:'huh-jy', kor:100, eng:100, math:100},
      		{name:'lee-ss', kor:60, eng:100, math:70},
      	]
      )
      
  • 위 예제데이터를 사용해서, multi 컬렉션에서 kor의 값이 70보다 큰(>) document를 가져와서 kor값의 평균 점수를 내보자.

    • db.multi.aggregate(
      	// stage 1: $match -> multi collection에서 kor filed의 값이 70 보다 큰 doc을 가져와라
      	{$match:{kor:{$gt:70}}},
      	// stage 2: 가지고온 doc에서 kor field만 가져오자
      	{$project:{kor:1}},
      	// stage 3: $group -> 전체 다 하나로 그룹화(test라는 이름으로) => 평균 구하자. ($avg) // kor field의 평균
      	{$group:{_id:'test','average':{$avg:'$kor'}}}
      )
      
    • image

    • kor의 값이 70보다 큰 경우는 100, 100 두개로 평균이 100으로 나온다.

    • $field : 해당 field 값을 사용할 때.(=$$current.field)
  • 해당 코드를 해석해보자.

    • db.multi.aggregate(
      	{$match:{name:/s/}},
      	{$group:{_id:'test', 'sum':{$sum:'$kor'}}}
      )
      
    • multi 컬렉션에서 name에 s가 들어가는 doc을 가져와서 test라는 이름으로 전체를 하나로 그룹화한 후, sum이라는 필드를 만들어 kor의 합계를 넣어줘라는 뜻
  • 예제 데이터2

    • db.score.insertMany([
         {name:"홍길동",kor:90,eng:80,math:98,test:"midterm"},
         {name:"이순신",kor:100,eng:100,math:76,test:"final"},
         {name:"김선달",kor:80,eng:55,math:67,test :"midterm"},
         {name:"강호동",kor:70,eng:69,math:89,test:"midterm"},   
         {name:"유재석",kor:60,eng:80,math:78,test:"final"},
         {name:"신동엽",kor:100,eng:69,math:89,test:"midterm"},
         {name:"조세호",kor:75,eng:100,math:100,test:"final"}
      ])
      
  • db.score.aggregate()

    • 이렇게 하면 find()랑 똑같이 나온다.
    • image
  • 원하는 필드만 True로 해서 뽑아낼 수도 있음

    • db.score.aggregate(
      	{$project:{_id:0, name:1, kor:1, eng:1, math:1}}
      )
      
    • image
  • 국어점수가 80점보다 큰 경우만 출력

    • db.score.aggregate(
          	{$match:{kor:{$gt:80}}}
      )
      
    • image
  • test라는 필드에 있는 값을 기준으로 그룹해 주고(midterm, final), kor필드에 있는 값을 가져와서 평균을 내라.

    • db.score.aggregate(
      	{$group:{_id:'$test','average':{$avg:'$kor'}}}
      )
      
    • image


Map Reduce

  • aggregation에서 처리하지 못하는 복잡한 집계 작업에 사용한다.
  • js 함수를 사용한다.
  • shard에 대응되 분산 처리가 가능하다.
    • 샤드(shard)란?
      • 샤딩(sharding)을 통해 나누어진 블록들의 구간(혹은 Epoch)을 말한다.
  • query -> map -> reduce -> out
    • query : 입력될 document
    • map : 데이터 가져오기(data mapping(grouping))
    • reduce : 집계 연산 실행(가져온 데이터로 작업)
    • out : collection or document 출력

예제

  • 예제 데이터

    • db.score.insertMany([
         {name:"홍길동",kor:90,eng:80,math:98,test:"midterm"},
         {name:"이순신",kor:100,eng:100,math:76,test:"final"},
         {name:"김선달",kor:80,eng:55,math:67,test :"midterm"},
         {name:"강호동",kor:70,eng:69,math:89,test:"midterm"},   
         {name:"유재석",kor:60,eng:80,math:78,test:"final"},
         {name:"신동엽",kor:100,eng:69,math:89,test:"midterm"},
         {name:"조세호",kor:75,eng:100,math:100,test:"final"}
      ])
      
  • test가 final인 doc 들의 이름, 국어, 영어를 출력하고 ‘국어와 영어의 합’도 같이 출력

    • 함수 생성

      • function myMap(){
        	emit(this.score, {name:this.name, kor:this.kor, eng:this.eng, test:this.test});
              
        }
              
        function myReduce(key,values){
        	var result = {name:new Array(), kor:new Array(), eng:new Array(), total:new Array()}
        	values.forEach(function(val){
        	if(val.test == 'final'){
        		result.name += val.name + " ";
        		result.kor += val.kor + " ";
        		result.eng += val.eng + " ";
        		result.total += val.kor + val.eng + " ";
        	}
        	})
        	return result;
        }
        
    • map, reduce, out

      • db.score.mapReduce(myMap, myReduce, {out: {replace:'myRes'}})
        
    • out값 확인

      • db.myRes.find();
        
      • image


PyMongo

환경 설정 및 설치

  • 참고 : https://pymongo.readthedocs.io/en/stable/tutorial.html
  • conda 가상환경 activate 후 설치
    • pip install pymongo
  • 모듈 호출

    • from pymongo import MongoClient
  • 클라이언트 지정(둘 중 하나)

    • client = MongoClient('localhost', 27017)
      client = MongoClient('mongodb://localhost:27017')
      
  • DB와 연결(둘 중 하나)

    • db = client.database명
      db = client['database명']
      
  • Collection 연결(둘 중 하나)

    • collection = db.컬렉션명
      collection = db['컬렉션명']
      

테스트

  • 아까 위에서 저장해논 test db에 있는 데이터들로 테스트해보자.

  • # pip install pymongo
    from pymongo import MongoClient
      
    # client = MongoClient('localhost', 27017)
    client = MongoClient('mongodb://localhost:27017')
      
    # db = client.test
    db = client['test']
      
    # collection = db.score
    collection = db['score']
      
    result = collection.find()
    # print(result)
    for res in result:
        print(res)
    
  • image

실습

(1) find

  • 모듈 호출

    • from pymongo import MongoClient
      from pprint import pprint # pretty 프린트임(이쁘게 출력)
      
  • 클라이언트 지정

    • client = MongoClient('localhost', 27017)
      
  • test db와 연결

    • db = client.test
      
  • score 컬렉션과 연결

    • score = db.score
      
  • 커서(curosr) 이용 조회

    • for문을 이용하지 않고 print(cursor)를 하면 커서 객체가 출력된다.

    • cursor = score.find()
      for doc in cursor:
          pprint(doc)
      
    • {'_id': ObjectId('62297f7311e3e38b4885825b'),
       'eng': 80.0,
       'kor': 90.0,
       'math': 98.0,
       'name': '홍길동',
       'test': 'midterm'}
      , ..
      {'_id': ObjectId('62297f7311e3e38b48858261'),
       'eng': 100.0,
       'kor': 75.0,
       'math': 100.0,
       'name': '조세호',
       'test': 'final'}
      
  • 국어 점수가 60점보다 큰 도큐먼트 전체 출력

    • kor_gt_60 = score.find({'kor':{'$gt':60}}, {'_id':0})
      for doc in kor_gt_60:
          print(doc)
      
    • {'name': '홍길동', 'kor': 90.0, 'eng': 80.0, 'math': 98.0, 'test': 'midterm'}
      {'name': '이순신', 'kor': 100.0, 'eng': 100.0, 'math': 76.0, 'test': 'final'}
      {'name': '김선달', 'kor': 80.0, 'eng': 55.0, 'math': 67.0, 'test': 'midterm'}
      {'name': '강호동', 'kor': 70.0, 'eng': 69.0, 'math': 89.0, 'test': 'midterm'}
      {'name': '신동엽', 'kor': 100.0, 'eng': 69.0, 'math': 89.0, 'test': 'midterm'}
      {'name': '조세호', 'kor': 75.0, 'eng': 100.0, 'math': 100.0, 'test': 'final'}
      

(2) insert

  • 참고 : https://pymongo.readthedocs.io/en/stable/api/pymongo/results.html#pymongo.results.InsertManyResult

  • score 컬렉션에 다음 조건의 데이터를 추가해보자.

    • 이름이 한지민, 국어점수 100, 영어점수 30, 수학점수 50
    • 이름이 송강, 국어점수 50, 영어점수 100, 수학점수 70
  • 모듈 호출 후 score 컬렉션에 접근

    • from pymongo import MongoClient
      from pprint import pprint
          
      client = MongoClient('localhost',27017)
      db = client.test
          
      score = db.score
      
  • 데이터 삽입

    • result01 = score.insert_many(
          [
              {'name':'한지민', 'kor': 100, 'eng': 30, 'math': 50},
              {'name':'송강', 'kor': 50, 'eng': 100, 'math': 70}
          
          ]
      )
      
  • 확인

    • cursor = score.find()
      for doc in cursor:
          print(doc)
          
      
    • image
  • 이번에는 이름이 신민아, 국어점수 50, 영어점수 70, 수학점수 100 으로 데이터를 하나 삽입해보자.

    • result02 = score.insert_one({'name':'신민아','kor':50,'eng':70,'math':100})
      
    • <pymongo.results.InsertOneResult object at 0x000001F1A6E18A80>
      622996b6cc3b36042ada59b1
      
  • 확인해보자.

    • cursor = score.find()
      for doc in cursor:
          print(doc)
      
    • image

(3) update

  • 참고 : https://pymongo.readthedocs.io/en/stable/api/pymongo/results.html#pymongo.results.UpdateResult

  • 이름(name)이 유재석인 도큐먼트를 찾아서 국어점수(kor)를 100점으로 변경하자.(doc 하나만 변경)

    • 모듈 호출 후 score 컬렉션에 접근

      • from pymongo import MongoClient
              
              
        client = MongoClient('mongodb://localhost:27017')
        db = client['test']
        score = db['score']
        
    • 수정

      • result01 = score.update_one({'name':'유재석'}, {'$set':{'kor':100}})
              
        print(result01.matched_count)
        print(result01.modified_count)
        
      • image

      • matched_count와 modified_count가 1이 뜬것으로 보아 수정이 잘 반영되었음을 알 수 있다.
  • 영어 점수가 80점보다 큰 사람들의 점수를 0점으로 바꿔보자.

    • result02 = score.update_many(
          {'eng':{'$gt':80}},
          {'$set': {'eng': 0}}
      )
      print(result02.matched_count)
      print(result02.modified_count)
      
    • image

    • 영어 점수가 80점보다 큰 데이터가 3개가 있었던 것으로 추정할 수 있다.

(4) delete

  • 참고 : https://pymongo.readthedocs.io/en/stable/api/pymongo/results.html#pymongo.results.DeleteResult

  • 이름이 유재석인 데이터를 삭제해보자.

    • result01 = score.delete_one({'name':'유재석'})
      print(result01)
      print(result01.deleted_count)
      
    • image

    • cursor = score.find()
      for doc in cursor:
          print(doc)
      
    • 조회해보면 잘 삭제된 것을 알 수 있다.
  • 이번에는 test 필드가 없는 도큐먼트를 모두 삭제해보자.

    • result02 = score.delete_many({'test':{'$exists':False}})
      print(result02)
      print(result02.deleted_count)
      
    • <pymongo.results.DeleteResult object at 0x000001E91C1834C0>
      3
      
    • 3개가 삭제가 된 것을 알 수 있다.

(5) aggregation

  • 참고

    image

  • Pymongo에서 aggregation 값은 리스트 형태로 들어가야 한다.

  • 국어 점수가 50점 보다 높은 데이터를 가져와서 id를 kor로 묶어주고 sum이라는 필드를 만들어 국어점수를 모두 더해주자.

    • aggr = score.aggregate(
          [
              {'$match': {'kor': {'$gt':50}}},
              {'$group': {'_id':'kor', 'sum':{'$sum':'$kor'}}}
          ]
      )
          
      print(aggr)
      print(list(aggr))
      
    • <pymongo.command_cursor.CommandCursor object at 0x00000152B5894100>
      [{'_id': 'kor', 'sum': 515.0}]
      

(6) 스타벅스 매장 정보 데이터를 가지고 실습

  • 이전에 크롤링으로 스타벅스 전국 매장정보를 가지고 있는 json파일을 만들었다.

  • 그 json 파일의 데이터를 가지고 실습해보자.

  • 우선 데이터를 불러와야한다.

    1. starbucks_all.json을 읽어온다.

    2. 읽어온 파일 한 줄 씩 json_data로 저장한다.

      import json
      with open('starbucks_all.json', 'r', encoding='utf-8') as f:
          json_data = json.load(f)
      
    3. json_data를 dictionary로 변환한다.(result_dict). 그리고 result_dict에 ‘list’라는 키를 입력하여, 리턴된 value를 반복문으로 출력하자.

      result_dict = dict(json_data)
           
      for data in result_dict['list']:
          print(data)
      
    4. 잘 나온다.

      image

  • 이제 pymongo를 사용해 볼 차례다.

  • 우선 MongoDB와 연결해보자.

    • db 는 test, collection은 starbucks01

    • # 모듈 호출
      from pymongo import MongoClient
      # 클라이언트 지정
      client = MongoClient('localhost', 27017)
      # test라는 db
      db = client.test
      # test라는 db 안의 starbucks01이라는 collection
      starbucks01 = db.starbucks01
      
  • 데이터들을 저장하고 데이터를 출력

    • result = starbucks01.insert_many(result_dict['list'])
          
      all = starbucks01.find({},{'_id':False})
      for data in all:
          print(data)
      
  • 명령프롬프트(cmd)에서 확인해보자.

    • db.starbucks01.find()
    • image
    • DB에 잘 저장되었다 :)

(7) 스타벅스 매장 정보 데이터로 GeoJson파일을 만들어 가까운 매장 출력하기

  • 이 데이터는 lat, lot 라는 키값을 가지고 있다.(위도/경도)

  • 그래서 GeoJSON파일을 만들어 볼 것이다.

  • 참고 : https://docs.mongodb.com/manual/geospatial-queries/

  • 매장명과 위 페이지에서 명시하는 데로 type과 coordinates를 구성했다.

    • import json
      from pymongo import MongoClient
          
      with open('starbucks_all.json', 'r', encoding='utf8') as file:
          json_data = file.readline()
          
      result_dict = json.loads(json_data)
          
      geo_list = list()
      for data in result_dict['list']:
          geo_dict = dict()
          geo_dict['s_name'] = data['s_name']
          coordinates = [float(data['lot']),float(data['lat'])]
          geo_dict['location'] = {'type': 'Point', 'coordinates':coordinates}
          
          geo_list.append(geo_dict)
      
  • 몽고DB에 삽입해주자.

    • client = MongoClient('localhost',27017)
      db = client.test 
      starbucks02 = db.starbucks02
          
      res = starbucks02.insert_many(geo_list)
      print(len(res.inserted_ids))
      
    • image

    • 1622개가 들어간 것을 확인
  • CMD에서 확인해보자.

    • db.starbucks02.find({},{_id:0})
    • image
  • 2dsphere인덱스를 생성한다.(숙제)

  • 우리 동네인 안양역 위도경도를 구글맵에서 가져오자.

    • image
    • 37.4027748742088, 126.92203909214015
  • cmd창에서 밑의 코드를 실행해보자.

    • coordinates에 넣을 때 위도, 경도 위치 잘 확인해야한다! [위도,경도] 형태로 들어가야 함

    • db.starbucks02.find(
      	{
              location:{
                  $near:{
                      $geometry:{
                          type:'Point',
                          coordinates:[126.92203909214015,37.4027748742088]
                      }
                  }
              }
          }
      )
      
  • 그러면 안양역과 가장 가까운 거리에 있는 순서대로 매장들이 나온다!

    • image
  • 이번에는 500m 반경 내로 제한해보자.

    • $maxDistnace: 미터(m)

    • db.starbucks02.find(
      	{
              location:{
                  $near:{
                      $geometry:{
                          type:'Point',
                          coordinates:[126.92203909214015,37.4027748742088]
                      },
                      $maxDistance: 500
                  }
              }
          }
      )
      
    • image

    • 안양역에서 500m 반경 내에 스타벅스가 3개나 있다 :)
  • 그렇다면 현재 위치(안양역)부터 ~ ‘서울’이라는 단어가 포함된 좌표들의 거리를 보고싶으면 어떻게 해야할까?

    • db.starbucks02.aggregate([
          {
              $geoNear:{
                  near:{type:'Point', coordinates:[126.92203909214015,37.4027748742088]},
                  spherical: true,
                  query: {s_name:/서울/},
                  distanceField: 'distance'
              }
          }
      ])
      
    • image

    • 관악서울대입구R 점이 매장명에서 ‘서울’이 들어간 곳 중 가장 가까운 매장인가보다.
  • 이번에는 안양역, 범계역, 평촌역 이렇게 삼각지대 안에 들어가는 스타벅스 매장을 찾아보고 싶다.

    • image

    • 좌표

      • 안양역 : 37.40273483013898, 126.92204547048901
      • 범계역 : 37.39009265979172, 126.95060553998034
      • 평촌역 : 37.39475864453516, 126.96476383067596
    • db.starbucks02.find(
      	{
              location:{
                  $geoIntersects:{
                      $geometry:{
                          type: 'Polygon',
                          coordinates:[
                              [
                                  [126.92204547048901,37.40273483013898],
                              	[126.95060553998034,37.39009265979172],
                              	[126.96476383067596,37.39475864453516],
                                  [126.92204547048901,37.40273483013898]
                              ]
                                  
                          ]
                      }
                  }
              }
          }
      )
      
    • image

    • 평촌아크로점, 안양범계점, 안양이마트점이 저 삼각 범위 안에 위치하는 지점들이다.
  • 이번에는 안양역을 기준으로 원을 그려서 그 안에 있는 매장들을 가져오자.

    • db.starbucks02.find(
      	{
              location:{
                  $geoWithin:{
                      $centerSphere:[[126.92203909214015,37.4027748742088], 0.5/3963.2]
                  }
              }
          }
      )
      
    • image

    • 매장 3개가 출력된다.

2022

[web]jQuery 복습 3

1 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]jQuery 복습 2

13 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]jQuery 복습 1

14 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]JavaScript 정리4

5 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]JavaScript 정리3

10 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]JavaScript 정리2

7 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]JavaScript 정리1

8 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]CSS 기초 정리

11 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[web]HTML 기초 정리

8 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

[Pandas]pandas 연습

3 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

맨 위로 이동 ↑

2021

[Python기초]module

1 분 소요

[Noitce] 고쳐야하거나 틀린 것이 있으면 말씀해주세요!

맨 위로 이동 ↑