Im currently working on assigning groups to a special url, with their groupId as score.
create group-url:
$this->cache->redis->zadd("group_route",$groupId,$groupUrl);
search if it is a group-url, and get the group:
function isCostumUrl($groupUrl) {
$group = $this->cache->redis->zrank("group_route",$groupUrl);
if ($group) {
return $group;
} else {
return false;
}
}
Problem My problem is that somehow the result-groupid is wrong.
I am searching for katt, that has id 4, but it reply with 3 wich acually belongs to group-url fisk.
how can i acually make it return the right result?
The rank is not the same with the score. The rank is zero -0- based, so in the case above rank 3 is correct for group_route katt. For example you can have different scores of your items 2, 3, 4 and 5, but the rank (or index) will always be the same. Take a look at the Redis rank command
But zscore would work correct for you (you actually put zscore in title, but use zrank in example)
Related
I have the following columns in my database using MySQL.
id|product_1|product_2|product_3|Total
1 25 25 25 75
However, let's say that I want to update one specific row in a form i.e. product_2 by 1.
id|product_1|product_2|product_3|Total
1 25 26 25 76
How do I accomplish the above using either Raw or Eloquent MySQL?
I've tried so many things like changing my code, searching on Google, YouTube, but I couldn't find a solution.
So the code below is what loads my table with populated data from MySQL.
public function index()
{
$ProductsPost = ProductsPost::all();
$sum_total = ProductsPost::select(DB::raw('product_1 + product_2 + product_3 as total_products'))->where('id', 1)->total_products;
return view('products/index')->with(
[
'products_post' => $ProductsPost,
'sum_total' => $sum_total
]
);
}
Below is my update function.
public function update(Request $request, $id)
{
$ProductsPost = ProductsPost::find($id);
$ProductsPost->update($request->all());
ProductsPost::where('id', $id)->sum('product_1', 'product_2', 'product_3');
if ($ProductsPost->wasChanged()) {
// changes have been made
return redirect('products')->with(['success' => 'Changes were successfully saved.']);
} else {
return redirect('products/'.$id.'/edit')->with(['error' => 'No changes made.']);
}
}
Am I supposed to add an update here to the total column?
Again, the result I'm looking for is the total sum of columns in a row based on id. For example, if product_2 changes to a different value, I want that reflected for the Total column. The Total column should sum the collection of values from the three columns product_1, product_2, product_3.
Sounds like a generated column, you can use the storedAs($expression) modifier in your migration as following:
Schema::create('products_posts', function (Blueprint $table) {
$table->double('product_1');
$table->double('product_2');
$table->double('product_3');
$table->double('total')->storedAs('product_1 + product_2 + product_3');
});
or
You may use the virtualAS($expression) modifier, which its value will be calculated on the fly, but based on your scenario you want to store the value and be update on the insert or update.
See the Documentation and this Question too.
Note
product_1, product_2, product_3 as columns, looks like you need to do some normalization.
You should add a 'On Update' constraint on your product_1, product_2 & product_3 column. On every update on this column, total will become sum of three product columns.
A question struck in my mind for 2 days and wondering whether it is possible to implement this type of tree structure in laravel and MySQL.
(First, take a look at the image attached. Thanks)
Suppose our platform uses refer system, and initially, a user 'A' join. Now, this user 'A' further refers 3 persons 'B','C','D'. Now, the total refer on A is 3 (because it refers 3 persons).
Now, let B further refers 'E','F' and 'C' further refers 'G','H', 'I' and 'D' refers 0. So, now refer of each person is "D = 0", "C = 3", "B = 2". and these refers will also add up on "A". So, it has "A = 8".
Now, 'G' refers 'J', so 'G' gets +1 and 'C' also gets +1 and 'C' is referred by 'A', so 'A' also gets +1. Now, total refer to each person is :
"j = 0","G=1","H=0","I=0", "D=0","E=0","f=0","B=2","C=4 (beacuse G refers J also)","A=9(beacuase 9 childers are refered by him)"
The chain continues until A gets total refer of 40.
In simple, if a person refers another person then it will get +1 and it's parent whom he gets refer also get +1 and so on until parent reaches 40, the chain continues.
I know, this is One-Many relationship between a user and refer and we can use a pivot table, but, How can we implement this type of logic. Give me some hints. Thanks.
I have written out something that should hopefully help you with this, using a while loop.
public function totalReferredBy(User $user)
{
// Initialise the queue to contain only the provided user
$queue = collect([$user]);
// This collection will eventually contain all of the "child"/referred users
$results = collect();
while ($queue->isNotEmpty() > 0) {
// Run a where in query to select all the referred users of the users in the queue.
$referredUsers = User::whereIn('referred_by', $queue->pluck('id'))->get();
// Merge the referredUsers we have found in the database with the results collection, so we can later count.
$results = $results->merge($referredUsers);
// Make the referredUsers we have just found in the database, the new queue. If the query did not return any
// referred users, the queue count would be 0 and the loop will exit.
$queue = $referredUsers;
}
// Now we should have all of the given user's "children" and "children of children" in the $results collection.
// We just need to return the count of that collection to get the total number of users that have been referred.
return $results->count();
}
You can use it like this:
$user = User::find(1);
$totalReferred = $this->totalReferredBy($user);
Then if your application does something when the user reaches 40 or more referred, you can just do:
if ($this->totalReferredBy($user) > 40) {
// Do something
}
This assumes that you have a referred_by column on the users table.
I have a issue that I cannot wrap my head around.
I am using the Laravel Framework.
I am trying to make a ranking table based on placement (Meaning the user does not have any SCORE, they just have placements)
How I want it to work is the following way:
User A = Placement: 1
User B = Placement: 10
User B wins over User A, then User B gets placed as number 1 and User A gets placed as number 2, and then I want it to update all the other users accordingly.
I can't seem to find a reliable way of doing this.
I don't think this is a Laravel challenge but an SQL one. And it may be simple to solve: basically, you will ask for the actual position of the defeated person, if the position is greater than the winner, you do nothing, otherwise you will assign the position of the loser to the new winner and update the rest of the table with a +1 in the position column.
In code it would be something like this:
$winner_player = User::where('id', userA->id)->first();
$loser_player = User::where('id', userB->id)->first();
if($winner_player->position < $loser_player->position) {
//Update the rest of the users.
//We add 2 because we need space for the new winner and for
//the loser that is still above of the rest of the players.
DB::table('users')
->where('position', '>', $loser_player->position)
->update(DB::raw('position+2'));
//Set the winner with the actual position of the loser.
$winner_player->position = $loser_player->position;
$winner_player->save();
//Set the looser with the new position (+1 of his actual).
$loser_player->position = $loser_player->position + 1;
$loser_player->save();
}
UPDATED LOGIC
As Classified pointed out, it moves the rows around but doesn't do it correctly, so I'm updating the logic to make it work as it is supposed to, and it will be a little simpler too.
$winner_player = User::where('id', userA->id)->first();
$loser_player = User::where('id', userB->id)->first();
if($winner_player->position < $loser_player->position) {
//Set the winner with the actual position of the loser.
$winner_player->position = $loser_player->position;
//Update the users between the swap. There is no need to update
//the whole table, we only update the records between the swap.
DB::table('users')
->where([['position', '<', $winner_player->position],
['position', '>=', $loser_player->position]])
->update(DB::raw('position+1'));
//Save the value of the winner AFTER updating the positions
//between winner and loser.
$winner_player->save();
}
I'am working on a API right now, and I'm on a part where I have to get a Players last matches score. Usually there are ATLEAST 2 teams in every match OR more. But I came across a playlist where there is only 1 team for the whole match.
I'am calling for the score of both teams like this:
// Get the Score AND Team ID of First team
$Warzonescore = $warzoneLastMatch->TeamStats[0]->Score;
$WarzonescoreTeamId = $warzoneLastMatch->TeamStats[0]->TeamId;
// Get the Score AND Team ID of Second team
$Warzonescore2 = $warzoneLastMatch->TeamStats[1]->Score;
$Warzonescore2TeamId = $warzoneLastMatch->TeamStats[1]->TeamId;
My problem is, in some matches, there is only 1 team, and if I load up a plyers gamertag, and if that person only played a match with one kind of team ( all players are on the same team), it gives me this error:
Undefined offset: 1
because TeamStats[1] does not exist for that player.
How can I get around that API call and check if that value is null, or if it exists?
I tried to insert it into a (if else) statement, and checked with ( ->exists(), === null, != 0, != "")
Doesn't make sense to hardcode your accessor methods in this way when you can do a simple loop on TeamStats
$Warzonescores = [];
foreach($warzoneLastMatch->TeamStats as $idx => $stats){
$Warzonescores[$idx]['Score'] = $stats->Score;
$warzonescores[$idx]['TeamId'] = $stats->TeamId
}
This seems like a more efficient and clean way to go about your approach. As it's an API, you can now do a simple and safe return on your data
return response()->json($Warzonescores);
Hi I want to show random 6 rows from a collection. each row as a timestamp so I could use that but my question is how do I return only 6 rows from the collection and make it random
here is a sample of my collection - I use PHP
{
"age": "2",
"breed": "Bengal",
"dislikes": "Dislikes being patted by people",
"likes": "Like to purr and get headbutts. Sleeps on our bed, with Woody our dog, and also comes in for food at 6pm, loves Tin fish and is known to meow quite lo [...]",
"lost": true,
"pet_lost_date": NumberInt(1361366445),
"type": "cat"
}
I saw this
db.items.find().skip(randonNumberHere).limit(1); - MongoDB: Pulling multiple random documents from a collection
but I did not understand it, all i understand from that is the find() which finds everything skip() which skips a number of rows and limit() which is how many get returned.
However My question is more about getting all the lost pets and random them and only showing 6
public function lost_pets($no){
$collection = static::db()->ipet_mypet;
$pet = $collection->find(array('lost': true, '$where'=> function(){var randomNumber=Math.random(); return this.random>=randomNumber || this.random>randomNumber })).sort(array('pet_lost_date'=> 1)).limit(6);
}
You could use this:
db.collection.find({'lost': true, $where: function(){var randomNumber=Math.random(); return this.pet_lost_date>=randomNumber || this.pet_lost_date>randomNumber }}).next();
Find({'lost':true}) fetches the documents with field 'lost': true.
The $where clause returns a DBCursor, which points to a particular document. By calling "next()", we obtain the next document pointed by the cursor. So we fetch one random document at a time.
According to the way I see it logically, the easy way is to save records with a random number, then sort by that number when reading from the db.
Let say you have 20 records
you want to randomly fetch 5 records
We will generate a random skip value between 0 to 20 - limit value (5) = 15.
With this we are sure to return 5 records even if the random skip value starts from 15. We can also force the skip value to be zero if its becomes negative after we substract the random value from the total records
Example code:
$total_records = $collection->count(); <br>
$limit = 5; <br>
$skip = mt_rand(0, $total_records);<br>
$collection->find()->skip($skip < 0 ? 0 : $skip)->limit($limit);