버전 2.0부터 Couchbase 서버는 뷰라는 개념을 통해 JSON 문서에 대한 인덱스를 생성하는 강력한 방법을 제공합니다.

보기를 사용하여 기본 인덱스, 복합 인덱스 및 집계를 정의하여 다음과 같은 작업을 수행할 수 있습니다:

다양한 JSON 속성에 대한 문서 쿼리

통계 및 집계 만들기

뷰는 구체화된 인덱스를 생성하므로 미리 정의된 쿼리를 실행하는 빠르고 효율적인 방법을 제공합니다.

이 블로그에서는 맵 및 축소를 사용하여 JSON 문서 속성을 색인하고 해당 속성을 기반으로 문서 순위를 결정하는 보기를 만드는 간단한 예제를 제공합니다.

지도와 축소를 사용하면 순위를 결정하는 매우 빠르고 효율적인 방법이며 수백만 명의 사용자에 걸쳐 확장할 수 있고 매우 빠른 순위 조회를 제공할 수 있습니다. 고마워요 Aaron 가르쳐 주셔서 감사합니다!

예를 들어 점수나 경험에 따라 사용자 순위를 매기는 데 사용할 수 있습니다.

이 블로그에서는 이름과 경험이라는 두 가지 속성을 가진 사용자 문서에 대한 개념을 설명하며, 경험을 기반으로 이 문서를 색인하고 경험 속성에 따라 순위를 결정할 수 있도록 합니다.


먼저 Couchbase 서버에 연결하고 사용자 문서를 만들 수 있는 몇 가지 Java 코드를 작성하겠습니다. 다음 Java 코드는 독립적인 코드이며 사용자를 생성합니다.

JSON 객체를 생성하기 위해 Gson Google 코드 라이브러리를 활용하고 있습니다.

 

패키지 블로그;

com.couchbase.client.CouchbaseClient를 가져옵니다;

com.couchbase.client.CouchbaseConnectionFactoryBuilder를 가져옵니다;

com.google.gson.Gson을 가져옵니다;

java.io.IOException을 가져옵니다;

java.io.UnsupportedEncodingException을 가져옵니다;

java.net.URI를 가져옵니다;

java.util.ArrayList를 가져옵니다;

UserDoc 클래스 {

   문자열 이름입니다;

   오랜 경험;

   UserDoc(문자열 이름, 긴 경험) {

       this.name = 이름;

       this.experience = 경험;

   }

}

/**

*

* 저자 알렉시스

*/

공용 클래스 RankView {

   비공개 정적 카우치베이스클라이언트 클라이언트;

   public static void main(String[] args) throws UnsupportedEncodingException, IOException {

       ArrayList 노드 = 새 배열 목록<>();

       // 클러스터의 노드를 하나 이상 추가합니다(사용자 노드와 IP 교환).

       nodes.add(URI.create("http://127.0.0.1:8091/pools"));

       // 클라이언트에 연결을 시도합니다.

       CouchbaseConnectionFactoryBuilder cfb = 새로운 CouchbaseConnectionFactoryBuilder();

       cfb.setOpTimeout(10000);

       cfb.setReadBufferSize(1024);

       cfb.setShouldOptimize(true);

       cfb.setTimeoutExceptionThreshold(100);

       시도 {

           client = new CouchbaseClient(cfb.buildCouchbaseConnection(nodes, "default", ""));

       } catch (Exception e) {

           System.err.println("카우치베이스에 연결하는 동안 오류가 발생했습니다: " + e.getMessage());

           System.exit(1);

       }

       UserDoc 사용자 = null;

       // 사용자 생성

       for (int i = 0; i < 10; i++) {

           user = new UserDoc("User" + i, Math.round(Math.random()*1000));

           Gson json = 새 Gson();

           문자열 jsonString = json.toJson(user);

           client.set(user.name, 0, jsonString);

       }

       client.shutdown();

   }

}

이 프로그램을 실행한 후(URL 또는 버킷 이름을 적절히 변경하세요) 이제 버킷에 10명의 사용자가 있어야 합니다.

 

다음 단계는 순위 보기가 있는 사용자 디자인 문서입니다.

첫 번째 단계는 경험 속성을 방출할 순위 보기용 간단한 맵을 만드는 것입니다:

함수 (문서, 메타) {

 if (doc.experience)

  emit(doc.experience, null);

}

이렇게 하면 경험 속성을 기반으로 인덱스가 생성되지만 순위를 결정할 수는 없습니다.

여기에 Reduce를 추가하는 것이 적합합니다. 간단한 내장 _count reduce를 추가하겠습니다.

전체 보기는 다음과 같이 표시되어야 합니다:

감소 함수를 사용하면 알려진 경험 값(doc.experience인 경우)을 가진 사용자 문서의 수를 집계할 수 있습니다.

쿼리 매개변수를 지정하지 않으면 생성한 문서 수인 10을 출력합니다.

특정 사용자의 순위를 조회하려면 먼저 특정 사용자(이 예에서는 User5)의 순위를 조회해야 합니다:

       // 특정 사용자 조회

       문자열 jsonString = (문자열) client.get("User5");

       user = json.fromJson(jsonString, UserDoc.class);

거기에서 최대 값으로 시작하여 더 큰 경험을 가진 모든 사용자를 캡처하고 사용자에 대한 가치로 끝나는 내림차순의 범위 쿼리로 이 수를 필터링하는 쿼리를 만들 수 있습니다:

       보기 보기 = client.getView("User", "Rank");

       쿼리 쿼리 = 새 쿼리();

       query.setIncludeDocs(true).setLimit(10000);

       query.setRangeStart(Long.toString(Long.MAX_VALUE));

       query.setRangeEnd(Long.toString(user.experience));

       query.setDescending(true);

       query.setReduce(true);

따라서 감소는 해당 사용자의 경험보다 더 큰 경험을 가진 사용자 수를 출력합니다. 순위는 단순히 해당 숫자 + 1입니다.

       뷰 응답 응답 = client.query(view, query);

       이터레이터 itr = response.iterator();

       while (itr.hasNext()) {

           ViewRow 행 = itr.next();

           System.out.println("Rank: " + Long.parseLong(row.getValue() + 1 );

       }

이렇게 하면 해당 사용자의 경험에 따라 순위가 출력됩니다:

순위: 7

전체 Java 코드(다시 자체 포함)는 다음과 같습니다:

패키지 블로그;

com.couchbase.client.CouchbaseClient를 가져옵니다;

com.couchbase.client.CouchbaseConnectionFactoryBuilder를 가져옵니다;

com.couchbase.client.protocol.views.Query를 가져옵니다;

com.couchbase.client.protocol.views.View를 가져옵니다;

com.couchbase.client.protocol.views.ViewResponse를 가져옵니다;

com.couchbase.client.protocol.views.ViewRow를 가져옵니다;

com.google.gson.Gson을 가져옵니다;

java.io.IOException을 가져옵니다;

java.io.UnsupportedEncodingException을 가져옵니다;

java.net.URI를 가져옵니다;

java.util.ArrayList를 가져옵니다;

java.util.Iterator를 가져옵니다;

UserDoc 클래스 {

   문자열 이름입니다;

   오랜 경험;

   UserDoc(문자열 이름, 긴 경험) {

       this.name = 이름;

       this.experience = 경험;

   }

}

/**

*

* 저자 알렉시스

*/

공용 클래스 RankView {

   비공개 정적 카우치베이스클라이언트 클라이언트;

   public static void main(String[] args) throws UnsupportedEncodingException, IOException {

       ArrayList 노드 = 새 배열 목록<>();

       // 클러스터의 노드를 하나 이상 추가합니다(사용자 노드와 IP 교환).

       nodes.add(URI.create("http://127.0.0.1:8091/pools"));

       // 클라이언트에 연결을 시도합니다.

       CouchbaseConnectionFactoryBuilder cfb = 새로운 CouchbaseConnectionFactoryBuilder();

       cfb.setOpTimeout(10000);

       cfb.setReadBufferSize(1024);

       cfb.setShouldOptimize(true);

       cfb.setTimeoutExceptionThreshold(100);

       시도 {

           client = new CouchbaseClient(cfb.buildCouchbaseConnection(nodes, "default", ""));

       } catch (Exception e) {

           System.err.println("카우치베이스에 연결하는 동안 오류가 발생했습니다: " + e.getMessage());

           System.exit(1);

       }

       UserDoc 사용자 = null;

       Gson json = null;

       // 사용자 생성

       for (int i = 0; i < 10; i++) {

           user = new UserDoc("User" + i, Math.round(Math.random() * 1000));

           json = 새 Gson();

           문자열 jsonString = json.toJson(user);

           client.set(user.name, 0, jsonString);

       }

       // 특정 사용자 조회

       문자열 jsonString = (문자열) client.get("User5");

       user = json.fromJson(jsonString, UserDoc.class);

       보기 보기 = client.getView("User", "Rank");

       쿼리 쿼리 = 새 쿼리();

       query.setIncludeDocs(true).setLimit(10000);

       query.setRangeStart(Long.toString(Long.MAX_VALUE));

       query.setRangeEnd(Long.toString(user.experience));

       query.setDescending(true);

       query.setReduce(true);

       뷰 응답 응답 = client.query(view, query);

       이터레이터 itr = response.iterator();

       while (itr.hasNext()) {

           ViewRow 행 = itr.next();

           System.out.println("Rank: " + Long.parseLong(row.getValue() + 1 );

       }

       client.shutdown();

   }

}

맵과 축소 보기를 사용하여 순위를 조회하면 클라이언트 측에서 추가 처리를 하지 않고도 빠르고 효율적으로 순위를 조회할 수 있습니다.

Couchbase의 보기 및 쿼리에 대해 자세히 알아보려면 다음을 참조하세요: http://www.couchbase.com/docs/couchbase-devguide-2.1.0/indexing-querying-data.html

질문 및 의견 alexis@couchbase.com 또는 트위터에서 @alexisroos를 팔로우하세요.

작성자

게시자 알렉시스 루스

Alexis Roos는 Salesforce의 선임 엔지니어링 관리자입니다. Alexis는 20년 이상의 소프트웨어 엔지니어링 경력을 보유하고 있으며, 지난 5년간은 대규모 데이터 과학 및 엔지니어링에 중점을 두고 유럽의 SI, Sun Microsystems/Oracle 및 Radius Intelligence, Concurrent, Couchbase를 비롯한 여러 스타트업에서 근무했습니다.

댓글 하나

  1. C 라이브러리의 구문이 자바의 \'setIncludeDocs\'와 일치하는지 궁금합니다.

  2. 카우치베이스에 게임 데이터를 저장하는 방법에 대한 개요입니다: http://www.couchbase.com/work

  3. 여러 사람이 같은 랭크에 있는 경우 1,2,3의 점수가 100점인 경우 항상 3등으로 랭크가 반환됩니다. 이 문제를 해결하는 방법을 모르겠습니다.

    1. user.experience 값이 일치하는 플레이어를 가장 낮은 순위가 아닌 가장 높은 순위로 반환하기 위해 (user.experience+1)을 쿼리한 다음 도출된 순위에 1을 더하는 해결 방법을 사용했습니다. 효과가 있는 것 같았습니다.

댓글 남기기