confused about Redis and how it will work - redis

I am following an article here and I think I want to go to hash route but I am confused as to what if I have multiple taxi_car
<?php
$redis->hset("taxi_car", "brand", "Toyota");
$redis->hset("taxi_car", "model", "Yaris");
$redis->hset("taxi_car", "license number", "RO-01-PHP");
$redis->hset("taxi_car", "year of fabrication", 2010);
$redis->hset("taxi_car", "nr_starts", 0);
/*
$redis->hmset("taxi_car", array(
"brand" => "Toyota",
"model" => "Yaris",
"license number" => "RO-01-PHP",
"year of fabrication" => 2010,
"nr_stats" => 0)
);
*/
echo "License number: " .
$redis->hget("taxi_car", "license number") . "<br>";
// remove license number
$redis->hdel("taxi_car", "license number");
// increment number of starts
$redis->hincrby("taxi_car", "nr_starts", 1);
$taxi_car = $redis->hgetall("taxi_car");
echo "All info about taxi car";
echo "<pre>";
var_dump($taxi_car);
echo "</pre>";
how would I create a database that has all the data about taxi_cars in redis. Now I know there is no database but keys in redis, but I am using the relational lingo here to express myself. If I have 1000 taxi_cars I do not want to have 1000 initial keys. It has to be subset of something. I am not sure how to even explain this.
EDIT
so lets say that under brand I have Toyota, Honda, Suzuki
and then under those I have different styles like Tacoma, Accord etc
how would I go on inserting that data and leter on retrieving it.
thanks

You should not try to map relational model concepts to a NoSQL store like Redis, but rather think in term of data structures and access paths.
Here are a number of simple examples:
Porting from SQLite to Redis
Work with keys in redis
how to have relations many to many in redis
Here you want to store records of car models. You first need something to identify them (i.e. a primary key in the relational terminology). Then you can store these records in the top level dictionary of Redis.
You should not store:
taxi_car => hash{ brand" => "Toyota", "model" => "Yaris", etc ... }
but:
taxi_car:1 => hash{ brand" => "Toyota", "model" => "Yaris", etc ... }
taxi_car:2 => hash{ brand" => "Toyota", "model" => "Prius", etc ... }
taxi_car:3 => hash{ brand" => "Tesla", "model" => "Model_S", etc ... }
Now, you need to anticipate the access paths. For instance to retrieve the cars per brand and model, you need to add extra sets (to be used as indexes):
brand:Toyota => set{ 1 2 }
brand:Tesla => set{ 3 }
model:Yaris => set{ 1 }
model:Prius => set{ 2 }
model:Model_S => set{ 3 }
So you can retrieve:
# Per brand
SMEMBERS brand:Toyota
-> returns 1 2
HGETALL taxi_car:1
HGETALL taxi_car:2
# Per model
SMEMBERS model:Prius
-> returns 2
HGETALL taxi_car:2
# Per brand and per model (a bit useless here), plus associated data
# sort is used to get all the taxi_car data in one shot
sinterstore tmp brand:Toyota model:Prius
sort tmp by nosort get taxi_car:*->brand get taxi_car:*->model etc ...

Related

Yii 1.1 relationship search issue

1. Table meeting
Model name CoreMeeting
Fields id, title, start time, created_by
Relationship:
'MeetingParticipants' => array(self::HAS_MANY, 'MeetingParticipants', 'meeting_id'),
2. Table core_meeting_participant
Model name is meeting_participant
Fields are id, meeting_id, participant_id, group_id
Relationship:
'meeting' => array(self::BELONGS_TO, 'CoreMeeting', 'meeting_id'),
'group' => array(self::BELONGS_TO, 'MeetingGroup', 'group_id'),
3. Table core_meeting_group
Model name is MeetingGroup
Fields are id, group_name
My search filter in the meeting model is:
public function search()
{
$group=filter_var($_REQUEST['group'], FILTER_SANITIZE_STRING);//contain group name
$criteria=new CDbCriteria;
$user_id = Yii::app()->user->id;
$criteria->compare('id',$this->id);
$criteria->compare('title',$this->title,true);
$criteria->with=array('MeetingParticipants'=>array("select"=>"*"),'MeetingParticipants.group'=>array('select'=>'id,group_name'));
if(isset($this->start_time) && !empty($this->start_time))
$criteria->compare('start_time',date("Y-m-d", strtotime($this->start_time)), true);
$criteria->compare('created_by',$user_id);
if(isset($group)&&!empty($group))
$criteria->compare('group.group_name',$group);
$criteria->together = true;
return new CActiveDataProvider($this, array(
'criteria'=>$criteria,
));
}
I have created 4 meetings, each meeting have at least 5 participants each participant belongs to a meeting group. I want to list all meetings with the following filed meeting title, groups and meeting time.
My problem is if I enable $criteria->together = true; if the meeting has more than 10 participants that will show only 1 meeting in grid view. If I disable this that will show all but I can't search with the meeting name.
SQL fiddle link is http://sqlfiddle.com/#!9/fdaacf
full SQL dump https://pastebin.com/NtpMuCpE
Documentation for CDbCriteria->together property:
https://www.yiiframework.com/doc/api/1.1/CDbCriteria#together-detail
Whether the foreign tables should be joined with the primary table in a single SQL. This property is only used in relational AR queries for HAS_MANY and MANY_MANY relations.
As I can see your relation in CoreMeeting model:
'group' => array(self::BELONGS_TO, 'MeetingGroup', 'group_id')
Obviously you are trying to fetch one-to-one (BELONGS_TO) relation CoreMeeting -> MeetingGroup eagerly by globally setting to your CDbCriteria->together = true; which is not correct according to the documentation.
What I would suggest you, first of all get rid of this global together setting to CDbCriteria and try changing your with clause like this:
$criteria->with = [
// this is your has-many relation (one meeting has several participants), thus we set here `together` to true
'MeetingParticipants' => [
'together' => true,
'with' => [
// this is your one-to-one relation (one participant has one group)
'group'
]
]
];

Selecting a status from several included entities in mvc 4 using entity framework 5

How do I select the status name of "barn doors open" in linq when using the include statement?
// GET: /Cowbow/Farm/
public ActionResult IndexNew()
{
var barns = dbFarm.Barn.Include(b => b.Dog).Include(b => b.Cat).Include(b => b.Pig).Include(b => b.Cow).Include(b => b.Chicken).Include(b => b.Feed);
// return View(barns.ToList()); // normal scaffold generated return
return View(barns.Where(b => b.Statuses.Where(s => s.statusName == "barn doors open")).AsEnumerable().ToList());
}
Barn also has a Status.StatusName field that has a foreign key relationship to the barnid. It also has two possible status names, "barn doors open", and "barn doors closed", and a date field when the status occurred and an id field. I can only add farm animals when barn doors are open.
Not sure if this is correct idea since there can be multiple statuses per barn.
How do I list out only those barns where the last status that occurred by date where the StatusName is "barn doors open"?
I tried to tack on a .FirstDefault but I want all Barns that contain "barns doors open" not just the first barn.
If I correctly understand you, in one certain moment your barn may have only one status (open or closed). So you don't need many-to-many ralation. Just write:
return View(barns.Where(a => a.Status.statusName == "barn doors open").AsEnumerable().ToList());
Are you looking for this...? :
return View(barns
.Where(b => b.Statuses
.Where(s => s.statusName == "barn doors open" &&
s.TimeStap == b.Statuses.Max(st => st.TimeStamp))
.AsEnumerable().ToList());
You also don't need to call .AsEnumerable().

Active Record- How to select a column with relationship?

Projects can have unlimited number of columns (to form a table or something), relationship MANY to MANY. To implement this tbl_project_rel_column is created. It stores project_id, column_id AND pos position of column in Project table.
I am using AC database approach. I have 2 models Project and Column.
Project model's relations method:
public function relations(){
return array(
...
'columns'=>array(self::MANY_MANY,'Column','tbl_project_rel_column('p_id','c_id')
);
}
Now can get all project's columns using something like this:
$model = Project::model()->findbyPk($p_id);
$columns = $model->columns;
But column doesn't store 'pos'(position) value of it's certain project.
How to get 'pos' value of tpl_project_rel_column table of certain project and certain column?
You can use the through feature instead of MANY_MANY. It may also be useful to index the results by the position column. Try something like this:
public function relations()
{
return array(
'projectColumns' => array(self::HAS_MANY, 'ProjectRelColumn', 'p_id', 'index'=>'position'),
'columns' => array(self::HAS_MANY, 'Column', 'c_id', 'through'=>'projectColumns'),
}
Now you can query for projects with columns like this:
$projects = Project::model()->with('columns')->findAll();
foreach($projects as $project) {
// projectColumns are indexed by position. You can sort by this now:
ksort($project->projectColumns)
foreach($project->projectColumns as $pos => $projectColumn)
echo "Pos: $pos Column: {$projectColumn->column->name}";
}

CGridview and Yii Active Record Relation

I have two tables tbl_business and business_contacts of the following structure:
tbl_business
---
business_id (PK)
othercolumns
and
business_contacts
---
contact_id (PK)
business_id
othercolumns
The scenario is that one business row has many contacts. I am using cGridview using gii's CRUD generator and needed to display firstname and lastname from business_contacts (one of multiple possible rows in the table) for each tbl_business record.
As far as I understand, I've updated the relation function in tbl_business's model as:
'businesscontacts' => array(self::HAS_MANY,'BusinessContact','business_id','select' => 'contact_firstname, contact_lastname')
and for the same, a contact relation is defined in the business_contacts' model as:
'contactbusiness' => array(self::BELONGS_TO,'BusinessContact','business_id')
I expected that would work for pulling related records so that I can have something in the grid like, business_id, contact_firstname, contact_lastname , ... otherbusinesstablecolumns .. but I'm only getting blank values under firstname and lastname .. could someone please help me understand the error? :(
So you are trying to display a table of Businesses (tbl_business) using CGridView? And in each Business's row you want to list multiple Contacts (business_contacts)?
CGridView does not support displaying HAS_MANY relations by default. CGridView makes it easy to list which Business a Contact BELONGS_TO (i.e. you can use a column name like contactbusiness.business_id), but not all of the Contacts that are in a business.
You can do it yourself though, by customizing a CDataColumn. (Note: this will not allow you to sort and filter the column, just view. You'll have to do a lot more work in to get those working.)
First, in your Business model, add a method like this to print out all of the contacts:
public function contactsToString() {
$return = '';
foreach ($this->businesscontacts as $contact) {
$return .= $contact->contact_firstname.' '.$contact->contact_firstname.'<br />';
}
return $return;
}
(EDIT: Or do this to print out just the first contact):
public function contactsToString() {
if($firstContact = array_shift($this->businesscontacts)) {
return $firstContact->contact_firstname.' '.$firstContact->contact_firstname;
}
return '';
}
Then make a new column in your grid and fill it with this data like so:
<?php $this->widget('zii.widgets.grid.CGridView', array(
'id'=>'business-grid',
'dataProvider'=>$model->yourDataProviderFunction(),
'columns'=>
'business_id',
array(
'header'=>'Business Contacts', // give new column a header
'type'=>'HTML', // set it to manual HTML
'value'=>'$data->contactsToString()' // here is where you call the new function
),
// other columns
)); ?>
EDIT2: Yet another way of doing this, if you just want to print out ONE of a HAS_MANY relation, would be to set up a new (additional) HAS_ONE relation for the same table:
public function relations()
{
return array(
'businesscontacts' => array(self::HAS_MANY,'BusinessContact','business_id','select' => 'contact_firstname, contact_lastname') // original
'firstBusinesscontact' => array(self::HAS_ONE, 'BusinessContact', 'business_id'), // the new relation
);
}
Then, in your CGridView you can just set up a column like so:
'columns'=>array(
'firstBusinesscontact.contact_firstname',
),
Getting only the first contact could be achieved like this also:
$this->widget('zii.widgets.grid.CGridView', array(
'id'=>'business-grid',
'dataProvider'=>$model->yourDataProviderFunction(),
'columns'=>
'business_id',
//....
array(
'name' => 'contacts.contact_firstname',
'value' => '$data->contacts[0]->contact_firstname', // <------------------------
'type' => 'raw'
);
//....
),

Tiered? structure of complex Zend Framework models/objects

What is the best way to store complex models in ZF? In the example below, should each attribute be a separate model entirely, or should the item be a multi dimensional array (as shown below)?
object(Application_Model_Item)#79 (4) {
["_id":protected] => int(45)
["_name":protected] => string(5) "Bolts"
["_description":protected] => NULL
["_attributes":protected] => array(2) {
[0] => array(2) {
["id"] => string(1) "3"
["name"] => string(4) "Size"
}
[1] => array(2) {
["id"] => string(1) "4"
["name"] => string(6) "Length"
}
}
Thanks in advance.
It all depends on your use case:
Indexing by ID or Position:
If you would like speed when accessing a particular attribute, then index the attributes by their IDs instead of their index position.
If you would like to keep an order, then order them by index position and a position offset amount.
Independent Table Vs Local Array:
If the attributes are duplicated in multiple items, then have them as their own table, and reference the attributes to that table.
If the attributes are not refenced and are unique to each item, then using them as serialise-able arrays (for storage) is adequate than needing them to be their own table.
In the case of _attributes i would use array of objects.
So it attributes would be an array of new model Attribute()
I make a class for every business model entity
["_attributes":protected] => array(2) {
[0] => Object(Model_Attribute) {}
[1] => Object(Model_Attribute) {}
}
class Model_Attribute {
protected $id;
public function getId();
public function setId($id);
.
.
.
}
I suggest you look at Doctrine ORM 2.0 since it can support the design from the above.
Look at this page, it may give you a clue:
http://www.doctrine-project.org/projects/orm/2.0/docs/reference/association-mapping/en