SQL++ 쿼리는 다양한 방식으로 Couchbase 클러스터에 저장된 데이터에 액세스할 수 있습니다. 데이터 쿼리의 일부로 비즈니스 로직을 포함하는 것이 유리할 수 있는 상황도 있습니다. SQL++는 사용자 정의 함수(UDF)를 통해 이를 지원합니다. Couchbase 7.0.
이 블로그 게시물에서는 SQL++를 사용하여 사용자 위치의 포인트를 동적으로 쿼리하는 UDF를 JavaScript로 만듭니다. 또한 파이썬에서 UDF를 사용하여 동일한 거리 계산을 수행합니다. 분석 서비스.
지리공간 쿼리 사용 사례
저희 애플리케이션은 아래 스크린샷에 표시된 것처럼 Google 지도와 같은 서비스와 유사하게 데이터베이스에서 사용자의 GPS 위치 근처에 있는 지리적 관심 지점을 생성합니다. 이 예제에서는 여행 샘플 데이터 세트 Couchbase에서 제공하는 샘플 버킷에서 사용할 수 있습니다.
특히, 저희는 랜드마크 그리고 공항 를 반환합니다. 거리 계산은 사용자의 실시간 지리적 위치를 기반으로 하므로 SQL++ 쿼리를 직접 사용할 수 없습니다. SQL++는 쿼리에서 사용자 지정 로직을 수행하기 위해 자바스크립트로 UDF를 정의하는 것을 지원합니다.

GPS 좌표로부터 거리 계산하기
두 GPS 좌표 세트 사이의 거리를 계산하는 방법에는 여러 가지가 있습니다. 이 예제에서는 두 좌표 세트 사이의 거리를 계산하기 위해 하버신 공식. 경로를 직선 거리가 아닌 구체로 간주하여 두 GPS 좌표 사이의 대략적인 거리를 제공합니다.
이 샘플에는 지리적 거리를 계산하는 자바스크립트 코드가 나와 있습니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
함수 degreesToRadians(학위) { 반환 학위 * 수학.PI / 180; } 함수 거리InKmBetweenEarth좌표(lat1, lon1, lat2, lon2) { var earthRadiusKm = 6371; var dLat = degreesToRadians(lat2-lat1); var dLon = degreesToRadians(lon2-lon1); lat1 = degreesToRadians(lat1); lat2 = degreesToRadians(lat2); var a = 수학.죄(dLat/2) * 수학.죄(dLat/2) + 수학.죄(dLon/2) * 수학.죄(dLon/2) * 수학.cos(lat1) * 수학.cos(lat2); var c = 2 * 수학.atan2(수학.sqrt(a), 수학.sqrt(1-a)); 반환 earthRadiusKm * c; } |
하나는 도(度)와 라디안 사이의 변환을 수행하는 JavaScript 함수이고 다른 하나는 다른 함수의 GPS 좌표 사이의 거리를 킬로미터 단위로 계산하는 함수입니다.
Couchbase로 UDF 가져오기
이제 이러한 자바스크립트 함수는 이제 REST API를 사용하여 아래 그림과 같이 curl 명령을 사용합니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
curl -v -X POST http://localhost:8093/평가자/v1/라이브러리/수학 -u <사용자>:<비밀번호> -d '함수 degreesToRadians(학위) { 반환 학위 * 수학.PI / 180; } 함수 거리InKmBetweenEarth좌표(lat1, lon1, lat2, lon2) { var earthRadiusKm = 6371; var dLat = degreesToRadians(lat2-lat1); var dLon = degreesToRadians(lon2-lon1); lat1 = degreesToRadians(lat1); lat2 = degreesToRadians(lat2); var a = 수학.sin(dLat/2) * 수학.sin(dLat/2) + 수학.sin(dLon/2) * 수학.sin(dLon/2) * 수학.cos(lat1) * 수학.cos(lat2); var c = 2 * 수학.atan2(수학.sqrt(a), 수학.sqrt(1-a)); 반환 earthRadiusKm * c; }' |
이 단계가 끝나면 웹 콘솔의 쿼리 편집기:
|
1 2 3 |
만들기 기능 degreesToRadians(a) 언어 자바스크립트 AS "degreesToRadians" AT "수학" 만들기 기능 거리InKmBetweenEarth좌표(lat1, lon1, lat2, lon2) 언어 자바스크립트 AS "거리InKmBetweenEarth좌표" AT "수학" |
여기에서 수학 참조는 자바스크립트 라이브러리 를 평가하기 위해 만들었습니다.
이제 SQL++에서 샘플 GPS 좌표를 사용하여 UDF를 테스트할 수 있습니다. 실행 기능 아래와 같이
|
1 |
실행 기능 거리InKmBetweenEarth좌표(51.5, 0, 38.8, -77.1) |
함수에 GPS 좌표를 수동으로 제공하면 함수가 의도한 대로 작동하는 것을 관찰할 수 있습니다.
UDF를 카우치베이스 데이터에 연결하기
에서 여행 샘플 데이터 세트의 GPS 좌표가 있습니다. 랜드마크 그리고 공항 와 같은 다른 관심 장소와 함께 호텔.
아래와 같이 쿼리에 통합할 수 있습니다:
|
1 2 3 4 5 6 |
선택 거리InKmBetweenEarth좌표(a.geo.위도, a.geo.lon, 51.509865, -0.118092) AS 거리, a.공항명, a.도시 FROM `여행-샘플`.인벤토리.공항 a 주문 BY 거리 ASC LIMIT 10; |
이 쿼리는 사용자 위치에서 가장 가까운 공항 10곳의 목록을 반환합니다(51.509865, -0.118092). 위도(a.geo.lat) 및 경도(a.geo.lon) 필드를 사용하여 문서에 내장된 SQL++의 기능을 사용할 수 있습니다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
[ { "공항명": "모든 공항", "city": "London", "거리": 0.6998675034052988 }, { "공항명": "워털루 국제", "city": "London", "거리": 0.7880158040048914 }, { "공항명": "런던 세인트 판크라스", "city": "London", "거리": 2.289359875405007 }, { "공항명": "유스턴 역", "city": "London", "거리": 2.30782110865356 }, { "공항명": "세인트 판크라스 기차역", "city": "London", "거리": 2.582290289682563 }, { "공항명": "패딩턴 스테이션", "city": "London", "거리": 4.069442660124984 }, { "공항명": "런던 헬기장", "city": "London", "거리": 6.062824964656381 }, { "공항명": "Elstree", "city": "Elstree", "거리": 8.735152174563803 }, { "공항명": "City", "city": "London", "거리": 12.009592036043564 }, { "공항명": "런던 - 킹스크로스", "city": "London", "거리": 16.891716659500467 } ] |
마찬가지로, 사용자 주변의 관심 지점을 계산할 수 있습니다. 랜드마크 사용자와의 거리가 멀어질수록 수집이 증가합니다:
|
1 2 3 4 5 6 7 |
선택 거리InKmBetweenEarth좌표(l.geo.위도, l.geo.lon, 51.509865, -0.118092) AS 거리, l.활동, l.도시, l.콘텐츠 FROM `여행-샘플`.인벤토리.랜드마크 l 주문 BY 거리 ASC LIMIT 10; |
주변 랜드마크를 표시하는 쿼리 결과입니다:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 |
[ { "활동": "참조", "city": "London", "content": "서머셋 하우스에는 세 개의 미술관이 있습니다: 드가, 마티스, 칸딘스키의 유명한 작품을 포함한 19세기 및 20세기 미술품을 전시하는 '코트툴드 인스티튜트''', 장식 예술품을 선보이는 '길버트 컬렉션'', 서머셋 하우스에 가장 최근에 추가된 '에르미타주 룸'에서는 상트페테르부르크의 에르미타주 박물관에서 대여한 작품을 임시 전시하고 있습니다. 여름에는 중앙 안뜰에 분수가 가득하지만 겨울에는 아이스링크가 설치되어 인기가 많으므로 미리 예약하지 않으면 스케이트를 타기 위해 오래 기다려야 할 수도 있습니다.", "거리": 0.10940067520415872 }, { "활동": "참조", "city": "London", "content": "클레오파트라의 바늘은 고대 [[이집트]]의 도시 [[카이로/헬리오폴리스|헬리오폴리스]]의 아툼 신전에서 유래했지만 로마인들이 기원전 12년에 [[알렉산드리아]]로 옮겼습니다. 1819 년 총독 메헤멧 알리는 이집트에서의 군사적 승리를 기념하여 클레오 파트라의 바늘을 영국에 선물했지만 1877 년 런던으로 가져 오기 위해 교통편이 마련될 때까지 알렉산드리아에 남아있었습니다. 항해 도중 폭풍우로 배가 전복되어 6명의 승무원이 사망했습니다. 클레오파트라의 바늘은 유실된 것으로 여겨졌지만 며칠 후 스페인 트롤 어부들이 물에 떠 있는 것을 발견했고, 수리를 거쳐 1878년 1월 21일 런던에 도착했습니다. 오벨리스크 옆에는 제2차 세계대전 당시 런던 폭격의 영향을 보여주는 두 개의 가짜 스핑크스가 있습니다. 오늘날 클레오파트라의 바늘은 런던의 습한 날씨에 노출되어 약간의 마모를 보여줍니다.", "거리": 0.2153782246329736 }, { "활동": "buy", "city": "London", "content": "템스 강변에서 매일 중고 서적을 판매합니다. 고전과 현대 서적, 지도, 인쇄물을 둘러보기 좋은 곳입니다.", "거리": 0.329776385402355 }, { "활동": "참조", "city": "London", "content": "[[런던]]([[런던/코벤트 가든|코벤트 가든]] 내)", "거리": 0.34889537479151833 }, { "활동": "참조", "city": "London", "content": "런던에서 가장 유명하고 인기 있는 스케이트보드 지역으로 퀸즈워크와 템즈강을 따라 퀸 엘리자베스 홀 아래 일부에 위치해 있습니다. 그래피티 아티스트, BMX 라이더 등에게도 인기 있는 곳입니다.", "거리": 0.36487940944981834 }, { "활동": "참조", "city": "London", "content": "워털루 다리 아래에 자리한 BFI 사우스뱅크는 과거 국립 영화관으로 알려진 곳으로 영화의 본고장이라고 자부하며 클래식(무성 영화 포함), 외국어 영화, 비주류 영화를 상영하는 3개의 스크린을 갖추고 있습니다. 최근 재개발을 통해 극장 골목에 새로운 입구가 생겼으며, 영화 전용 상점과 인터랙티브 전시 공간, 뒤편에 훌륭한 바/레스토랑이 있습니다. 방문객들은 또한 미디어테크에 입장하여 BFI의 방대한 영화 및 TV 아카이브를 무료로 둘러볼 수 있습니다. 멋진 바와 레스토랑. 티켓은 일반적으로 즉석에서 구매할 수 있습니다.", "거리": 0.378692262237853 }, { "활동": "참조", "city": "London", "content": "매일 공연이 열리는 음악 공연장. | 이미지=퀸 엘리자베스 홀.jpg", "거리": 0.3859430181613397 }, { "활동": "drink", "city": "London", "content": "게이 바의 해독제: 펍과 같은 분위기와 멋진 음악. | 이미지=더 레트로 바.jpg", "거리": 0.39732030942983415 }, { "활동": "참조", "city": "London", "content": "올리비에, 리텔톤, 코테슬로의 세 개의 대형 강당이 있습니다. 올리비에 극장은 가장 큰 규모로 무대가 개방되어 있고 주변에 부채꼴 모양의 강당이 있습니다. 따라서 모든 좌석에서 좋은 시야를 확보할 수 있습니다. 다른 극장보다 공간이 훨씬 넓기 때문에 대부분의 '인기 있는' 작품이 이곳에서 공연됩니다. 리텔튼 극장은 프로시니엄 아크가 있는 전통적인 극장이며 대부분의 좌석에서 좋은 전망을 제공합니다. 코테슬로는 약 400석 규모의 소규모 스튜디오 극장입니다. 일부 티켓은 당일 좌석(09:30 이전에 도착하여 줄을 서야 함) 또는 대기석(오후 6시 이전에 도착하여 줄을 서야 함)으로 당일 구매하거나 온라인으로 구매할 수 있습니다. 특히 올리비에의 크리스마스 공연과 같은 인기 공연은 몇 달 전에 매진됩니다. 국립극장 티켓은 일반적으로 대부분의 다른 극장보다 저렴합니다. 여름에는 10파운드에 많은 좌석(연간 10만 석 이상)을 제공하는 '10파운드 트래블엑스' 시즌도 있습니다. 이 경우 사전 예약이 필요합니다. 리텔튼 극장 로비에는 인기 사진 전시회가 자주 열리는 전시 공간도 있습니다. 저녁에는 1층 로비에서 무료 재즈 공연이 종종 열립니다. 여름에는 매일 공연, 음악, 코미디, 카바레가 어우러진 무료 야외 축제인 '워치 디스 스페이스'가 열립니다. 데크 의자(및 인조 잔디)가 제공되어 관람할 수 있습니다. 무료 전시회. 백스테이지 투어 £5. (http://www.nationaltheatrelondon.com/tickets/)", "거리": 0.42625112040817054 }, { "활동": "drink", "city": "London", "content": "매일 밤 무료 음악 이벤트. 언더그라운드 일렉트로, 인디, 덥 스텝 등을 맛볼 수 있는 최고의 장소입니다.", "거리": 0.4323026974543284 } ] |
여러 사용자에 대해 동시에 이러한 쿼리를 실행하는 경우, Couchbase 클러스터의 일부인 컴퓨팅 리소스를 사용하기 때문에 성능 문제가 발생할 수 있습니다.
이러한 시나리오에서 Couchbase Analytics는 클러스터에 미치는 영향을 줄일 수 있습니다. 카우치베이스 애널리틱스는 많은 레코드에 대한 복잡한 쿼리를 효율적으로 실행하도록 설계되었습니다. 복잡한 쿼리에는 대규모 임시 조인, 집합, 집계 및 그룹화 작업이 포함될 수 있으며, 이러한 작업은 데이터 가져오기 및 노드 간 조정으로 인해 쿼리가 오래 실행되거나, CPU 사용량이 많거나, 메모리가 많이 소모되거나, 네트워크 지연 시간이 과도하게 발생할 수 있습니다.
카우치베이스 애널리틱스를 사용한 사용자 정의 함수
카우치베이스 애널리틱스를 통해 다음을 정의하고 사용할 수 있습니다. 파이썬의 사용자 정의 함수 하지만 이 글을 쓰는 시점에서는 다음을 수행해야 합니다. 개발자 미리 보기 활성화 모드로 전환합니다. 다음 명령으로 이 작업을 수행할 수 있습니다:
|
1 2 |
$ /opt/카우치베이스/bin/카우치베이스-cli 활성화-개발자-미리 보기 \ --활성화 -c localhost:8091 -u <사용자 이름> -p <비밀번호> |
다음 단계는 개발 환경에서 파이썬 UDF를 사용하여 로컬로 파이썬 패키지를 생성하는 것입니다. 이 경우 UDF는 두 GPS 좌표 사이의 거리를 계산하는 방법입니다.
|
1 2 3 4 5 6 7 |
# distance.py 에서 지리 가져오기 거리 클래스 거리 계산: def 계산_거리(self, lat1, lon1, lat2, lon2) -> float: """측지 거리를 사용하여 거리 계산""" 반환 거리.거리((lat1, lon1), (lat2, lon2)).km |
여기서는 측지 거리 (곡선 경로를 따라 점 사이의 최단 거리)를 라이브러리의 도움으로 두 GPS 좌표 사이의 거리로 계산합니다, 지리.
UDF 패키징
라이브러리를 패키징하려면 패키지를 사용합니다. shiv 를 사용하여 모든 플랫폼에 대한 요구 사항과 함께 코드를 패키징할 수 있습니다. 여기서는 카우치베이스 서버가 Docker 내의 Linux 환경에서 실행되고 있으므로 Linux를 사용하고 있습니다.
|
1 |
shiv -o 거리.pyz --사이트-패키지 . --플랫폼 manylinux2010_x86_64 --python-버전 39 --만-바이너리=:모두: 지리 |
이 바이너리 패키지를 UDF와 함께 Couchbase에 업로드하기 위해서는 REST API 애널리틱스 서비스용입니다.
|
1 |
curl -X POST -u <사용자 이름>:<비밀번호> -F "type=python" -F "data=@./distance.pyz" localhost:8095/분석/라이브러리/기본값/pylib |
이렇게 하면 패키징된 UDF를 pylib 라이브러리의 기본값 범위 (이전 데이터버스)를 클릭합니다. 이제 분석 환경의 분석 워크벤치.
이 정의 문은 다음과 같은 이름의 UDF를 정의하고 있음을 나타냅니다. distance_in_km 파이썬 함수에서 호출할 수 있는 계산_거리 클래스에 정의된 거리 계산 파이썬 모듈 내에서 거리.
|
1 2 |
만들기 분석 기능 distance_in_km(lat1, lon1, lat2, lon2) AS "거리", "거리 계산.계산_거리" AT pylib; |
이제 SQL++ 쿼리에서 UDF를 사용한 것과 동일한 방식으로 Analytics 쿼리에서 UDF를 사용할 수 있습니다.
|
1 2 3 4 5 6 7 8 |
선택 distance_in_km(51.5, 0, 38.8, -77.1) AS "거리" 결과: [ { "거리": 5933.5299530300545 } ] |
분석 서비스에서 데이터 서비스의 데이터 매핑하기
분석 서비스에서 데이터 서비스의 데이터를 쿼리하려면 다음을 수행해야 합니다. 지도 의 여행 샘플 데이터 컬렉션을 사용하여 Analytics의 데이터 서비스에서 데이터의 실시간 섀도 복사본을 만듭니다. 이 예제에서는 컬렉션을 지리적 데이터, 즉 랜드마크, 공항 그리고 호텔 인벤토리 범위의 컬렉션에서 여행 샘플 버킷.
카우치베이스 데이터에 대한 분석 UDF 실행
이제 이전에 SQL++에서 실행했던 것과 동일한 쿼리를 분석 서비스에서 실행할 수 있습니다. UDF 이름만 변경되었습니다. 나머지 인터페이스는 SQL++ 쿼리에서 사용했던 것과 유사합니다. 결과도 이전 결과와 유사합니다.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
선택 distance_in_km(a.geo.위도, a.geo.lon, 51.509865, -0.118092) AS 거리, a.공항명, a.도시 FROM `여행-샘플`.인벤토리.공항 a 주문 BY 거리 ASC LIMIT 10; 선택 distance_in_km(l.geo.위도, l.geo.lon, 51.509865, -0.118092) AS 거리, l.활동, l.도시, l.콘텐츠 FROM `여행-샘플`.인벤토리.랜드마크 l 주문 BY 거리 ASC LIMIT 10; |
이 접근 방식은 이러한 쿼리를 실행하면서 데이터 서비스 트랜잭션 데이터에 일반적으로 사용됩니다. 데이터는 데이터 및 분석 서비스 내부적으로 Couchbase에서 실시간으로 확인합니다.
요약
이 블로그 게시물에서는 두 GPS 좌표 사이의 거리를 계산하는 사용자 정의 함수(UDF)를 JavaScript로 만드는 방법을 배웠습니다. UDF를 Couchbase로 가져온 다음 이를 SQL++ 쿼리에 통합하여 사용자 주변의 관심 지점을 제공할 수 있는 애플리케이션을 구동하는 방법을 살펴보았습니다. 또한 트랜잭션 Couchbase 클러스터에 미치는 영향을 줄이기 위해 Analytics 서비스를 사용하여 Python 기반 UDF에서 동일한 거리 계산을 수행하는 방법도 보여드렸습니다.
자세한 내용을 읽고 참고하려면 다음 리소스를 참조하세요: