Aerospike + Spring: Why does PK type always change to varchar? - spring

Entity (very simple, for the test):
#Document(collection = "user_repo")
public class User {
#Id
private int id;
private String name;
private int age;
}
Repository
public interface AerospikeUserReactiveRepository extends ReactiveAerospikeRepository<User, Integer> {
}
Requested data from the database:
aql> select * from test
+-------------+----------------------------------------+------------------+-----------+
| PK | name | #_class | age |
+-------------+----------------------------------------+------------------+-----------+
| "761637962" | "21b50081-c244-4e98-9e5d-7b346f549154" | "com.model.User" | 761637962 |
| "626513063" | "7a171a11-b275-488b-ac29-e92b3f6f8668" | "com.model.User" | 626513063 |
| "422312771" | "c51ea6c5-840b-40eb-8616-e3447b363097" | "com.model.User" | 422312771 |
+-------------+----------------------------------------+------------------+-----------+
3 rows in set (0.053 secs)

You are right,
In Spring Data Aerospike the PK is stored as a String, initially it was done because:
It has an advantage of being able to have any type of key/change the key on application layer without changing persistence layer.
It gives readable format in Aerospike when you need to see data directly in storage.
Spring Data Aerospike supports Composite Keys so for saving them as a readable string the most simple approach is using to string conversion.
Currently you can change it by using Custom Converters.
We do consider to support storing primitive types as it is out-of-the-box, it's in our backlog.

Related

Is it possible to get last elements grouped with JPA and Spring boot

I have a data set that looks like this:
name | rang
boo | 4
boo | 2
boo | 1
foo | 3
foo | 1
zoo | 2
zoo | 1
I want to select through spring boot jpa:
name | rang
boo | 4
foo | 3
zoo | 2
I do ofcause have a larger and more complex dataset, so the example is simplify.
I was hoping to find something like this:
#Repository
public interface FooRepository extends CrudRepository<FooDb, String> {
Set< FooDb > findAllByNameAndMaxDate(String name);
}
I think you may be able to do this by using the #Query annotation.
In your case it might look something like:
#Query("SELECT t.name, MAX(t.rang) FROM table t WHERE t.name=?1 GROUP BY t.name")
Set<FooDb> findAllByNameAndMaxDate(String name);
Without knowing what your data set looks like it's impossible for me to create the query here, but I hope this helps.

Custom fields design for multiclient application

I have a question releated to application design. I have a ecommerce application which is used by 9 clients. Every client has the same copy of application with different frontend template. App is designed under laravel and it's updating on every customer server to keep up-to-date. So every app have the same backend("engine"), same database design etc.
Problem is that two of the clients wants a custom fields to for CRUD pages. With current update mechanism every client will get those fields which is not what i want.
I've been thinking about adding separate table to database to keep there a configuration of all fields - like a map of table columns. So when app is used controller will call configuration table to get list of fields and foreach them in view.
+---+---------------+-------------------+------------+
|id |controller | field_name |field_type |
+---+---------------+-------------------+------------+
| 1 | products | price_retail | integer |
| 2 | manufacturers | name | varchar |
| 3 | manufacturers | logo | varchar |
| 4 | manufacturers | custom_for_client | integer |
+---+---------------+-------------------+------------+
Is it a valid - good idea?
Without knowing exactly what you plan to do with these "fields", I can only make suggestions.
Have you considered the use of a json column to store data for fields that aren't applicable to all users?
Database Migration
...
$table->json('meta')->nullable();
...
Model
...
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
...
'meta' => 'array',
...
];
...
You can then access the "fields" within this json object like so:
$model->meta['column'];
or iterate over then like so:
collect($model->meta)->each(function ($column) {});
https://laravel.com/docs/7.x/eloquent-mutators#array-and-json-casting

Retrieving User's Name from Query

I have an Employee evaluation form which stores the supervisor (FTO) and employee (FTE) in the database by their ID number (EID).
I can retrieve the data and display the EID of both the supervisor and the employee, but how can I setup it up to pull their names from the user table and display those?
My User Table
ID | EID | first name | last name | email | password
Evaluation Table
ID | ftoEid | fteEid | date | rating1 | etc...
Currently using in the model:
$dor = Dor::find($id);
return view('dor.show', compact('dor'));
You need to set up relationships.
class Evaluation extends Model {
public function user() {
return $this->belongsTo("App\User", 'fteEid');
}
}
Dor::find(1)->user->first_name;
Your field names are confusing so I am not sure if they are correct; hopefully you get the idea.

can I use laravel 4 eloquent model or do I need to use db:query

Hi I am trying my first attempt to use ORM with Laravel. I have a big table from Drupal that I want to grab some records of and I need to join those with another table in Drupal to get the records that I care about manipulating.
Like so...
Node
----------------------------------------------------------
| Nid | type | misc other stuff | N
==========================================================
| 1 | Programs | Test Service | 1 |
----------------------------------------------------------
| 2 | Programs | Example Service | 1 |
----------------------------------------------------------
| 3 | Something else | Another Service | 1 |
----------------------------------------------------------
Fields
----------------------------------------------------------
| id | title | NID | tag |
==========================================================
| 1 | Blog Title 1 | 1 | THER |
----------------------------------------------------------
| 2 | Blog Title 2 | 2 | TES |
----------------------------------------------------------
| 3 | Blog Title 3 | 3 | ANOTHER |
----------------------------------------------------------
I want to get all the Nodes where type='Programs' and inner join those with all fields where NIDs are the same. Do I do that with an Eloquent ORM in app/model/node.php? Or a query builder statement $model=DB:table? what is the code for this? Or do I just do it in PHP?
You could do this with the ORM, but would have to override everything that makes it convenient and elegant.
Because you say you're trying to "manipulate" data in the fields table, it sounds like you're trying to update Drupal tables using something other than the Drupal field system. I would generally not recommend doing this—the Drupal field system is big, complicated, and special. There's a whole CMS to go with it.
You should move the data out of the old Drupal database and into your new database using seeds (http://laravel.com/docs/4.2/migrations#database-seeding).
Define a "drupal" database connection in your app/config/database.php, in addition to whatever you're using as a "default" connection for a new application. You can seed Eloquent models from an alternative connection in this manner:
<?php
// $nodes is an array of node table records inner joined to fields
$nodes = DB::connection('drupal')
->table('node')
->join('fields', 'node.nid', '=', 'fields.nid')
->get();
Pull the data out and put it in proper tables using Laravel migrations into normalized, ActiveRecord-style tables (http://laravel.com/docs/4.2/migrations#creating-migrations).
I prefer query builder, it's more flexible
DB::table('Node')
->join('Fields', 'Fields.NID', '=', 'Node.Nid')
->where('type', 'Programs')
->get();
Create two models in app/model (node.php and field.php) like this:
class Node extends \Eloquent {
protected $fillable = [];
protected $table = 'Node';
public function fields()
{
return $this->hasMany('Field');
}
}
class Field extends \Eloquent {
protected $fillable = [];
public function node()
{
return $this->belongsTo('Node');
}
}
Than you could do something like this:
$nodes = Node::with('fields')->where('type', 'Programs')->get();
You will get all your nodes with their relation where type is Programs.

Laravel 4: A better way to represent this db structure/relationship within laravel

I have the following db table set up
+--------------+ +--------------+ +-----------------------+
| users | | clients | | user_clients |
+--------------+ +--------------+ +----------------------+
| id | | id | | usersid |
| name | | name | | clientid |
| authid | | email | +----------------------+
| (plus) | | (plus) |
+-------------+ +-------------+
I have set up the a relationship table [b]user_clients[/b] with foreign keys to the relevant db, so userid is link to users->id and clientid is linked to clients->id.
Dependant on the Users Authid is how many clients are linked:
Authid 1: User can only have one client associated to them.
Authid 2: User can only have one to many clients associated to them
Authid 3: User has access to ALL clients.
So as i am new to this relationship side of laravel currently i would do a lot of querying to get some details eg:
I would done something like:
$userClient =UsersClients::select('clientid')->where('userid','=',$userid)->get();
Then I would probably loop through the result to then get each client details and output to the page.
foreach($userClient as $i ->$cleint){
echo '<div>' .$cleint->name . '</div>';
........
}
Would this be an old way and could it be handled better??
----------------EDIT---------------
i have managed to sort it as the following:
User Model:
public function clients() {
return $this->hasMany('UsersClients','userid');
}
User Controller
$selectedUserClients = User::find(24)->clients;
I get the same out come as my previous result as in client id's 1 & 2, but now how to get the client details from the actual client db basically is there an easier way that the following:
foreach ($selectedUserClients as $key => $client) {
$clientInfo = Client::select('id','clientname')->where('id','=',$client->clientid)->get();
echo $clientInfo[0]->clientname;
}
The users_clients table needs it's own ID column in order for many-to-many relationships to work.
On your User Model, try
public function clients()
{
return $this->belongsToMany('Client','user_clients','userid','clientid');
}
Now you can find the clients assigned to each individual user with
User::find(24)->clients.
You could also do the inverse on your Client model...
public function users()
{
return $this->belongsToMany('User','user_clients','clientid','userid');
}
This would allow you to find all the users belonging to each client
Client::find(42)->users;
I would also like to mention that it's best practice to use snake case for your id's such as user_id or client_id.
Your table names should be plural. users and clients.
Your pivot table should be snake_case, in alphabetical order, and singular. client_user.
This would make working with Eloquent much easier because it's less you have to worry about when setting up the relationships and it might be easier for someone else to help you work on your project.
Instead of return $this->belongsToMany('Client','user_clients','userid','clientid'); all you'd have to do is return $this->belongsToMany('Client'); which should keep your app much cleaner and easier to read.

Resources