Couchbase
  • Why NoSQL?
  • Couchbase Server
  • Download
  • Resources
  • Careers
Home | Forums | SDKs | SDKs

NoSQL Data Modeling Confusion

2 replies [Last post]
  • Login or register to post comments
Fri, 09/16/2011 - 05:36
bnutting
Offline
Joined: 02/03/2011
Groups: None

Perhaps I am too new to NoSQL and I’ve been living in a relational database far too long, but I did have some questions and figured I would ask the community. 

I watched the Couchbase 2.0 tutorial and demo and he referenced a game with data objects “Player”, “Item”, and “Monster”. Since this is not a real world example for me I will use my example, then ask questions. 

Suppose we have Users and Groups, where users can have one or many authorized groups. In a relational database this is how I would setup the data.

User is defined as:
ID
Username
Password 

Group is defined as:
ID
Name

User Authorization to Group:
User_ID
Group_ID

Typical queries are as follows:
Search for user by ID (this one is easy since the key is ID)
Search for user by username
Search for group by ID (this one is easy since the key is ID)
Get all groups for a user
Get all users for a group

Since membase/couchbase are key/value based...how do we accomplish these queries without going through ALL keys? And in Spymemcached you can’t get all keys and there’s no way to query. Again sorry for my relational database mind-set. I understand that Couchbase 2.0 helps with some of this with views, but I have not seen anything in Spymemcached to call a view let alone with parameters.

The other piece I didn’t really understand is in Spymemcached they reference CAS in various places, but I have yet to find anything about what CAS is supposed to be…and I’ve googled a fair amount to find it.

Thanks for all of your help. Sorry in advance for my newbie questions.

Top
  • Login or register to post comments
Wed, 09/21/2011 - 11:01
mikew
Offline
Joined: 03/14/2011
Groups:

I'm not an expert with setting up Couchbase views (used for querying) yet so I'm going to let someone else answer those questions, but I do want to address you questions about Spymemcached. First off, you are correct that Membase is a key/value store, but Couchbase is a json document store. Since Couchbase is based on CouchDB you can read here for a short intro to what documents are and how they are queried (http://couchdb.apache.org/docs/intro.html). This link will also answer your question about how queries are accomplished.

In Spymemcached there is a way to do Queries. My guess is that you probably don't have the latest version of Spymecached. You will need at least version 2.8 (Note that at the moment we only offer developer preview of spy 2.8). Check out the tutorial for Spymemcached to see how to run queries on view http://docs.couchbase.org/couchbase-sdk-java-tutorial/index.html. You will have to scroll down to the end of the document for information on using Spymemcached with Couchbase Server.

CAS is a check and set operation which means "store this data but only if no one else has updated since I last fetched it." When doing certain calls to memcached you can get a CAS value with is a 64 bit number. Whenever a value is changed its CAS is incremented. So when you do a CAS you put the last CAS value you got for that key into the message and memcached will only change the value of the corresponding key if no one else has changed the key already.

Top
  • Login or register to post comments
Thu, 09/22/2011 - 06:37
BigBlueHat
Offline
Joined: 01/28/2011
Groups: None

Couchbase is very well suited for the scenario you described. Depending on what other Group related meta-data you want to store, you could might be able to get away with just a database of user documents that reference a restricted set of group names:

{"_id": "username", "password": "passw0rd", "groups":["accounting", "marketing", "engineering"]}

{"_id": "otheruser", "password": "passw0rd", "groups":["engineering"]}

In the documents above I've dropped a numeric or UUID-based ID in favor of using the username as the ID. That's not a requirement, but certainly makes things simpler.

The above docs alone satisfy your first two queries with simple GET (thinking CouchDB's HTTP API here) requests:
- search for user by ID or by username (as they're the same now).

It also satisfies the "get all groups for a user" query.

The remaining two queries ("search for group by ID" and "get all users for a group") can be satisfied by a single map/reduce query:

Map:

function(doc) {
  if (doc.groups && doc.groups.length > 0) {
    doc.groups.forEach(function(group) {
      emit(group, doc._id);
    });
  }
}

Reduce:
_count
This "_count" reducer is built-in and calls an Erlang-based counting function, so it's much faster than writing the same thing in JS.

The output of the above map would be a single line per group with the username associated to the group name:

[{"key":"accounting", "value":"username"},
 {"key":"engineering", "value":"otheruser"},
 {"key":"engineering", "value":"username"},
 {"key":"marketing", "value":"username"}]

The full reduction of this query would return:

[{"key": null, "value": 4}]

This is the total number of group references, *not* the total number of unique groups.

We can also do grouped reduction which is far more useful in this case. You'd get this result by adding "?group=true" to the _view request:

[{"key": "accounting", "value": 1},
 {"key": "engineering", "value": 2},
 {"key": "marketing", "value": 1}]

The results of this query get you the count per group, but can also be used to satisfy the "search for group by ID." You can pass in an additional query parameter, "key", to a _view request to find the exact count for a specific group. Sending in ?group=true&key="engineering" will result in:
[{"key": "engineering", "value": 2}]

I hope that answered some of your questions. Even if your documents are a bit more complex than these, the approach should be repeatable on a wide range of scenarios.

Hope that helps. If not, keep asking questions. :)

Thanks,
Benjamin

Top
  • Login or register to post comments
  • Login or register to post comments
  • Login
  • Register

Company

  • About Us
  • Leadership
  • Customers
  • Partners
  • Contact Us

Product

  • Couchbase Server
  • Couchbase SDKs
  • Use Cases
  • Documentation
  • Forums

Open Source

  • Couchbase Project
  • Couchbase vs. CouchDB

Commercial

  • Subscriptions & Support
  • Training & Services

News

  • Blog
  • Newsletter
  • Press Releases
  • Buzz

Follow Us

    
  • Customer Login
  • Terms of Service
  • Privacy Policy
  • Trademark Policy
  • Site Map

© 2013 COUCHBASE All rights reserved.

Sign in to Couchbase Community

close
  • Create new account
  • Request new password
You are logging into the Forums, Wiki and Issue Tracker