Couchbase JSON structure model - php

I want to work with couchbase json-document oriented.
But I don't know what's the best way to store and structure data and retrieve it later.
Is there somehow any tutorial to get started (the learing resources on couchbase.com did not help)?
I'm using PHP to access to couchbase.
I've got the following sample:
(new document)
user1
{
"uid":1,
"name":"marius"
}
(new document)
planet1
{
"pid":1,
"user_uid":1,
"name":"earth"
}
(new document)
user2
{
"uid":2,
"name":"anyone"
}
(new document)
planet2
{
"pid":2,
"user_uid":2,
"name":"saturn"
}
Now what would be the smartest way to set (insert) these documents into the database and how can I get (select) the documents by selection.
To say it in SQL I want to -> SELECT * FROM user,planet WHERE user.uid=1 AND planet.user_uid=1

Couchbase stores data differently than a relational database.
There are two main ways to get data out of Couchbase:
Key/Value. This means you give your document one key to query on and then obviously the value is going to be the entire document. So for a user:
user = couch.get(123)
That would return the entire document for user ID 123.
Views. You can write views in Couchbase using map/reduce functions. The cool thing is that these views can be accessed in a similar way to views in CouchDB, so you can do things like ordering and limiting. http://wiki.apache.org/couchdb/HTTP_view_API#Querying_Options
Check out the design documents/views in your Couchbase portal. When you write one it'll give you a URL to test your map/reduce stuff. Then you can add parameters to the URL to do additional work.

There is no general way in saying how your documents should be designed. It do depend on the characteristics of your app. Write vs Read ratio? How is the data consumed etc. With the strengths of transforming data using views in couch, I guess you could make more "generic" documents and create specific views that transform the doc to fit your use-case. Of course not a solution that you should apply to all use-cases (don't see it as the silver-bullet design).
A classic example is the blog example. Should you store comments in the post or extract comments and have the reside on their own, with a reference? It depends on the characteristics. Is it more common to have a few comments or is it usually loads of comments?
Another sample. What if you store a order document. Should the customer be part of the order or the order of the customer? Could it be both? Yes, it could. I would say that with document dbs you need to be a bit more open to duplication of data. Could it be that the Customer doc still exists as the "current view" of the customer, with all his data and the Order contains fragments of a customer snapshot; useful for the order-context and some overview in the app, which then uses references to the actual customer doc? Probably. But again, it depends on how you would consume the data.
Regarding SQL translation: http://www.couchbase.com/docs/couchbase-manual-2.0/couchbase-views-writing-sql.html

Related

Drupal 8 store node data alternative in store

Don't have much of a code example just a question and an idea.
I want to be able to save node data (from content creation) into an in-house datastore using elastic DSL queries.
I have heard/seen slides about Drupal supporting MongoDB to extent which makes me think this is doable. Even if I have to override the NodeForm/save handler is there a way to manipulate the node entities for this purpose?
This is perfectly doable. We're using Elasticsarch in all our Drupal projects, mainly to use it for full-text searches. Every node is saved twice:
one time in Drupal's database, this is the node use in every code line
one time in an Elasticsearch index, this one is never "used" ; we use full-text searches to find nids, then we retrieve the full object in Drupal DB
You can use elasticsearch_connector module to get an easy-to-use manager like this:
$cluster = Cluster::load('ES-CLUSTER');
$clientManager = \Drupal::service('elasticsearch_connector.client_manager');
$client = $clientManager->getClientForCluster($this->cluster);
And then use this client to manage your nodes' indexation:
function hook_node_insert($node) {
$client->insert($node);
}
function hook_node_update($node) {
$client->update($node);
}
function hook_node_insert($node) {
$client->delete($node);
}
The biggest part of the work is to create your mapping (if you want it to be manageable via a module), but here again elasticsearch_connector will give you tools for it:
$client->indices()->putMapping($params);
$client->indices()->putSettings($params);
$client->search($params);
My idea is to have them saved twice. First, to have normal nodes and second by using those "elastic DSL queries" (not sure what they are).
Anyway, you could use hook_node_presave() which would be called every time normal node saving will be done and there you can place your code for that "elastic DSL" saves. From that hook you can access data that will be saved but you can also alter them if you need to do that.

How to implement a server-side querying solution for mongo db references

I am relatively new to Mongo DB, but I am finding that is merges nicely with a project that I am working on. I am currently stuck at a problem however that I am really struggling to resolve...
This is specifically related to mongo db's "manual" references, documented here: http://docs.mongodb.org/manual/reference/database-references/#document-references
The project that I am working on sees every single document as a re-usable object instance, meaning that it can be embedded within another document, and because I am using manual references along with the client-side to resolve the references, it works really well. The issue arises when I want to be able to find objects, based on the value of one of the child objects.
A likely scenario:
we have an Orders collection which stores generated shop orders. An order object has a property named "products" which when viewed in mongo db is an array of references to product objects.
we also have a Products collection which stores products that can be used in orders.
say we want to be able to find all orders that contain the product "foo-bar", and bearing in mind that the path order.products is an array of references (not the embedded objects), what would be the most efficient way to do this? The most ideal solution would be the ability to simply use order.products.name : 'foo-bar'
A few additional notes:
fetching all order objects from the database and having the client-side resolve the objects to filter out the ones that we're looking for is far too inefficient.
embedding the product documents inside of the order documents is not an option, as it is essential to be able to modify the order and product documents independently of each other.
I am accessing mongo db using a PHP framework (and the official mongo db php extension)
a server-side solution would be ideal
I have briefly looked into the ability to write custom functions on mongo's server-side, but I can't quite tell if that would be a potential way to go?
Seems that you want to use joins (a term from SQL). Mongodb has no support for joins or alternative techniques.
The simplest thing that can work here is two-step query (pseudo-code)
product_ids = db.products.find(name: 'foo-bar').only('id')
orders = db.orders.find(product_id: {$in: product_ids})
This way you don't download a bunch of product objects onto the client, only their ids. It works quite well for me in my apps.
But this task is, of course, much better handled by a real relational DB.

Use of models in FuelPHP?

I'm new to PHP frameworks and to start my venture I went to try FuelPHP. After a few days of testing around I understood how things work. Controllers control the actions, views control the $content and the template controls the layout. But what about models, What are they for?
Models are abstractions over data stored elsewhere, they encapsulate the data access through standard object creation, method calls, property access, etc. just like ordinary objects. The main idea here is that the controller (or whatever object that requires the data) doesn't need to know how to get the data or how it's stored. It could be stored in files, web (via webservice), database, whatever thing that could persist data. The data could be retrieved with webservice request, database query, file reading, etc.
For instance, "gimme student record with id 1" could be as simple as student := new student(1); and after that you have access to the student's name, address, etc. But how does the student retrieve its data? Where does it store the data? It's out of concern and could be tuned (or should be tunable) as needed.
models controle your data and have a direct contact with your db have a read here
You might have say
Contact With ID,Name,Detail and ContactType properties.
The idea is to keep it minimal it's basically something to cart around all the useful properties of an entity.
This is the current definition of MVC. Nothing about the backend in it. That would be some seperate library / dll that only knows about model, and how the underlying data is stored in the DB.

Why make Objects when you can just use a MySQL database?

So I am a little confused on the object oriented part of PHP. Right away I will apologize for the fact I know very little about PHP and databases.
My question is when you are making, say, a database to hold users in it, why would you want to make a class/object for that user when you can just pull info from the database?
Also, if you were to make a object/class where is the data for the objects stored? For example, if I have a class with a username and email, and I make that object, were does it get stored?
Thanks for taking your time to help a learning noob!
My question is when your making per
say a database to hold users in it,
why would you want to make a
class/object for that user when you
can just pull info from the database.
You make objects to abstract away specific functionality. What happens if you move to, say, Microsoft SQL Server (hypothetically speaking)? Rather than update your entire site, you just edit the implementation of the object.
Also if you were to make a
object/class where is the data for the
objects stored? Like a class with a
username and email, and I make that
object, were does it get stored.
The same place as any other variable.
There are a LOT of reasons why you want to use some abstraction on top of just raw database access in any reasonably large software system. If you're looking at an Object Oriented approach you should consider that one of the core ideas of the Object Oriented paradigm is that an object encapsulates both data and logic that acts on that data.
Let's take a concrete example. Say that a part of your application (the UI) needs to display user information, including a nicely formatted user name. In an OO world you could have a User object which would store a local copy of the data in the database, and expose methods like getFormattedName(), or something similar. Now the rest of your application can use that code without needing to know about the database, or even how the name is formatted. On the other hand if you were just pulling data directly from the database then the UI part of the application (which doesn't really care about databases) still has to know itself how to get information about the user from the database, and how to format the users name nicely.
To put it simply, there are logic not captured in a database table but related to the entry. The database only stores the raw data. How the data is used and how it interacts with the rest of your application should be captured in your object methods.
You're missing a fundamental of object-oriented design. Ignoring inheritence entirely, Objects combine information/data and functions/procedures/operations into a single unit called an object. This object performs operations (methods/behaviors/functions/procedures) and has attributes. A database will not have the entire set of operational/procedural information. By design, a database will only contain data, and know nothing of how the data can be used or what the data does.
Databases store data in a tabular fashion which is designed to be speedy. Objects are so much more flexible; they can be trees, they can be lists, they can be widgets, or anything else out of a million things. They can represent presentation, data, or structure. And sometimes they are even faster (when it's easier to calculate a value on the fly rather than retrieve it from a database). Databases are very powerful and important but are only appropriate for a small subset of the tasks that a web application performs. The rest are made easier by objects.

MySQL Status Model -- Best Implementation?

So I'm working on a framework-esque system with one of my co-workers. Our current challenge is how to best implement statuses. Oftentimes, a status will carry with it unique data (a color for a table row, or text to be displayed to a user. etc). Currently, we have a statuses table which contains all this data. Contained in that table is a column: "css_class", which, whenever a record has that status, the specified CSS class is attached to the element (in this case a tr). Also, in order to assign another record a specific status, a foreign key is specified in that database table (in this case, a user has a specific status. So in the users table, there is a statuses_id foreign key). This implementation works alright, but there are a few problems. First, what if I need to perform a specific action in PHP if a record is in a specific status? The way we do it now is something like this:
if($user->status==0)
{
//execute some code
}
This really doesn't work well if statuses can change. Change one status, and the associated code either breaks or behaves differently than intended.
The other issue, and the main reason for posting a question is that the table contains the column "css_class". This is very versatile and allows us change the style of a specific status very quickly. But we really dislike the idea of putting code inside a database. Perhaps having CSS classes in a database isn't necessarily a bad thing, but I really don't know what the common practice is. Any ideas?
EDIT:
What I've gathered from the first few answers is that I should keep all my view stuff out of my model stuff in order to maintain an MVC framework. My argument is that if I keep the css_class name out of the database, then I'm checking the status id in the view in order to decide which class to assign it. So if I put the class in the database, I'm putting View information in the Model. If I don't put CSS classes in the database then I'm putting Model information in the View (checking which ID it belongs to). So by not muddying up the Model, I muddy up the view instead.......
The most elegant way I've seen this solved so far (and I've worked with a few MVC implementations now) is to store only the relevant data in the database. E.g. you'd store status="red" in the database, and leave it up to the view to know what to do with a red status, in terms of CSS. The problem is then solved by designing a sufficiently advanced View layer that creates reusable structures -- that way you don't need to always be updating things on a page-by-page basis when the css changes.
Passing this information up to the Model somewhat defeats the point of the content/presentation separation, because now your code needs to know to pull presentation information off the database and forward it along to the View level or, shudder, you'll be pulling that stuff from the database right in your View layer code, which makes maintenance a nightmare, as you've now lost control over the information flow.
If you want to continue your paradigm of storing this in the DB, you could make another table that maps VARCHAR names of the statuses to their corresponding INTEGER IDs.
However, if this was my framework. I would not be storing view information like this in the database. This would be handled by the V of my MVC setup.
From a data modelling point of view:
Have a different table for each "kind" of status; keep user statuses separate from page statuses (for example) - group the like entities together.
Don't put the CSS classes into the database, but use some form of status indicator - this could be an ENUM column, if you know the set of possible statuses up front. Transform this into the appropriate CSS class in the view layer. You don't want to end up in a situation where your CSS can't be changed because some data in the database prevents it.

Categories