문제

회원이 활동을하고 Google Appengine을 사용하여 다른 회원의 활동을 따르는 소셜 애플리케이션을 설계하는 가장 좋은 방법이 무엇인지 궁금합니다.

보다 구체적으로 말하면 우리는 다음 엔티티를 가지고 있다고 가정 할 수 있습니다.

  • 사용자 친구가있는 사람
  • 활동 사용자가 작성한 작업을 나타내는 (각각은 소유자 사용자에게 문자열 메시지와 참조 증명서가 있거나 Appengine의 키를 통해 부모 협회를 사용할 수 있다고 가정 해 봅시다)

어려운 부분은 친구의 활동을 따르는 것입니다. 즉, 모든 친구의 최신 활동을 집계하는 것을 의미합니다. 일반적으로 활동 테이블과 친구 목록 사이에 가입 한 것이지만 조인 시뮬레이션이 없기 때문에 Appengine의 실행 가능한 디자인은 아닙니다. N 쿼리를 발사 한 다음 메모리에서 병합해야합니다. 매우 비싸고 아마도 요청 마감일을 초과 할 것입니다 ...)

나는 현재 새로운 활동의 생성이 새로운 활동의 키를 다음 모든 사용자의 "받은 편지함"에 넣을 배경 프로세스를 발사 할 수있는받은 편지함 대기열을 사용 하여이 구현을 생각하고 있습니다.

  • "X를 따르는 모든 사용자"를 얻는 것은 가능한 AppEngine 쿼리입니다.
  • 기본적으로 (사용자, 활동 키) 튜플을 저장하는 새로운 "받은 편지함"엔티티에 매우 비싼 배치 입력이 아닙니다.

이 디자인이나 대안 제안 등에 대한 생각을 기꺼이들을 것입니다.

도움이 되었습니까?

해결책

보세요 앱 엔진에서 확장 가능하고 복잡한 앱 구축 (PDF), Brett Slatkin의 Google I/O에서 주어진 매혹적인 대화. 그는 트위터와 같은 확장 가능한 메시징 서비스를 구축하는 문제를 해결합니다.

여기에 있습니다 해결책 목록 속성 사용 :

class Message(db.Model):
    sender = db.StringProperty()
    body = db.TextProperty()

class MessageIndex(db.Model):
    #parent = a message
    receivers = db.StringListProperty()

indexes = MessageIndex.all(keys_only = True).filter('receivers = ', user_id)
keys = [k.parent() for k in indexes)
messages = db.get(keys)

이 키 전용 쿼리는 수신기 목록을 제외하고 직렬화하지 않고 지정된 수신기와 동일한 수신자가있는 메시지 지수를 찾습니다. 그런 다음이 지수를 사용하여 원하는 메시지 만 가져옵니다.

여기에 있습니다 잘못된 방법 그것을 위해 :

class Message(db.Model):
    sender = db.StringProperty()
    receivers = db.StringListProperty()
    body = db.TextProperty()

messages = Message.all().filter('receivers =', user_id)

쿼리가 쿼리에서 반환 한 모든 결과를 포장을 풀어야하기 때문에 비효율적입니다. 따라서 각 수신기 목록에 1,000 명의 사용자가있는 100 개의 메시지를 반환하면 100,000 (100 x 1000) 목록 속성 값을 사로화해야합니다. 데이터 스토어 대기 시간 및 CPU에서 너무 비싸다.

나는 처음 에이 모든 것에 꽤 혼란 스러웠다. 그래서 나는 목록 속성 사용에 대한 짧은 튜토리얼. 즐기다 :)

다른 팁

나는 그것이인지 모른다 베스트 소셜 애플리케이션을위한 디자인 자이쿠 ~였다 앱 엔진으로 포팅되었습니다 회사가 Google이 인수했을 때 원래 제작자이므로 합리적이어야합니다.

섹션을 참조하십시오 배우와 호랑이와 곰, 오 마이! 안에 design_funument.txt. 엔티티는 정의됩니다 Common/Models.py 그리고 쿼리가 있습니다 공통/api.py.

Robert, 귀하의 제안 된 솔루션에 대해 :

messages = Message.query(Message.receivers == user_id).fetch(projection=[Message.body])

NDB.TextProperty "Body"는 색인이 없어서 예측과 함께 사용할 수 없다고 생각합니다. 예측은 인덱스 속성 만 지원합니다. 유효한 솔루션은 메시지와 MessageIndex의 두 테이블을 유지하는 것입니다.

NDB의 새로운 프로젝션 쿼리로 이것이 해결 될 수 있다고 생각합니다.

class Message(ndb.Model):
    sender = ndb.StringProperty()
    receivers = ndb.StringProperty(repeated=True)
    body = ndb.TextProperty()

messages = Message.query(Message.receivers == user_id).fetch(projection=[Message.body])

이제 목록 속성을 사로화하는 데 드는 비싼 비용을 처리 할 필요가 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top