What If Divar Loves NOSQL

Case study

Mongo DB

Document Database

Key Features

  • High Performance

    1. Embedded data models
    2. Indexes
  • High Availability

    1. Automatic fail over
    2. Data Redundancy

Key Features

  • Horizontal Scalability

    1. Sharding
    2. Tag
  • Multiple Storage Engines

    1. WiredTiger
    2. Memory

Terminology and Concepts

SQL Terms/Concepts MongoDB Terms/Concepts
table collection
row document
column field
table joins embedded documents and linking
aggregation aggregation pipeline

Read/Write Concern

  • Read Concern

    • local
    • majority
  • Write Concern

    • number
    • majority
    • tag

Atomicity and Transactions

  • Document Level Isolation (include embeded documents)
  • $isolated Operator (exclusive lock on collection)
  • two phase commit

Mongo Engine

Post User Info

class PostUserInfo(EmbeddedDocument):
    email = EmailField(verbose_name=u"Email", max_length=250, required=False, validation=[VALIDATOR_EMAIL])
    phone = StringField(max_length=32, verbose_name=_(u"Phone number"), validation=[VALIDATOR_PHONE])
    device_id = StringField(max_length=48)
    platform = StringField(verbose_name=_(u"Sender platform"), max_length=1, choices=POST_PLATFORM_CHOICES, default="A")
    ip = StringField(default='0.0.0.0', required=False, null=True)
    phone_numbers = ListField(StringField(StringField(max_length=32, validation=[VALIDATOR_PHONE])))
    cloud_id = StringField(verbose_name=_(u"Cloud ID"), required=False, null=True)
    chat_id = StringField(verbose_name=_(u"Chat ID"), required=False, null=True)

Publishe Able Post

class PublishablePost(AbstractPost):
    # fields
    images = ListField(FileField())
    fields = DictField()

    # configs
    last_modified = DateTimeField(verbose_name=_(u"Last modification date"), default=datetime.datetime.now)
    promotions = IntField(default=0, verbose_name=_(u"Promotions"), help_text=PROMOTIONS_HELP_TEXT)
    sort_date = DateTimeField(verbose_name=_(u"Sort date"), null=False, required=True)
    clean_state = IntField(default=1, null=False)
    hide_email = BooleanField(default=False)
    paid_for_link = BooleanField(verbose_name=_(u"Paid for link"), default=False)

    meta = {'allow_inheritance': True}
class AbstractPost(Document):
    token = StringField(max_length=9, required=True, default=helper.random_token, unique=True)
    created_at = DateTimeField(verbose_name=_(u"Send date"))

    categories = ListField(IntField(null=True, validation=[VALIDATORS_SMALLINT]))
    places = ListField(IntField(null=True, validation=[VALIDATORS_SMALLINT]))

    post_user_info = EmbeddedDocumentField(PostUserInfo)

    meta_version = IntField(verbose_name=_(u'Meta version'))

    meta = {'allow_inheritance': True}

Abstract Post

class PublishablePost(AbstractPost):
    # fields
    images = ListField(FileField())
    fields = DictField()

    # configs
    last_modified = DateTimeField(verbose_name=_(u"Last modification date"), default=datetime.datetime.now)
    promotions = IntField(default=0, verbose_name=_(u"Promotions"), help_text=PROMOTIONS_HELP_TEXT)
    sort_date = DateTimeField(verbose_name=_(u"Sort date"), null=False, required=True)
    clean_state = IntField(default=1, null=False)
    hide_email = BooleanField(default=False)
    paid_for_link = BooleanField(verbose_name=_(u"Paid for link"), default=False)

    meta = {'allow_inheritance': True}

Published Post


class OngoingPost(AbstractPost):
    publish_state = StringField(verbose_name=_(u"Publish state"), max_length=1, choices=POST_PUBLISH_STATE_CHOICES, default="I")
    admin_check_level = IntField(default=0)
    last_modified_by_user = DateTimeField(verbose_name=_(u"Last modification by user"), null=True, required=False)
    mng_token = StringField(max_length=14, unique=True, default=helper.random_token_long)
    already_published_post = ReferenceField(PublishedPost)

    image_change = DictField()
    stats = DictField()
    first_published_at = DateTimeField(verbose_name=_(u'First publication date'), required=False, null=True)
    objection_note = StringField(verbose_name=_(u"Objection note"), required=False, default=None, null=True)

    reviews = ListField(EmbeddedDocumentField(Review))

OngoingPost


class Review(DynamicEmbeddedDocument):
    reviewer = ReferenceField(User)
    reviewed_at = DateTimeField(verbose_name=_(u"Review date"), required=False, null=False, default=None)

    reason = StringField(verbose_name=_(u"Review reason"), max_length=1, choices=REVIEW_REASON_CHOICES, default="S")
    result = StringField(verbose_name=_(u"Review result"), max_length=1, choices=REVIEW_RESULT_CHOICES, default="U")

Review


class Report(EmbeddedDocument):
    device_id = StringField(max_length=48)
    platform = StringField(verbose_name=_(u"Sender platform"), max_length=1, choices=POST_PLATFORM_CHOICES, default="A")
    ip_address = StringField(verbose_name=_(u"IP address"), default='255.255.255.254')

    reason = StringField(verbose_name=_(u"Reason"), max_length=1, choices=REPORT_REASON_CHOICES)
    last_modified = DateTimeField(verbose_name=_(u"Last modification"), default=datetime.datetime.now)
    desc = StringField(verbose_name=_(u"Description"), required=False, default="")

Report

What If?

What If Divar Was designed by

By Behnam Hatami

What If Divar Was designed by

  • 937