MongoDb/php Get max id value on a collection - php

I want to get the max id value on a collection.
How do I convert the mongoDb query:
db.tweets.find({},{id:1}).sort({id:-1}).limit(1)
to Mongo Query Language Statement using PHP?
I'm trying
$db->tweets->find(
array(),
array("id"=>1)
)->sort(array("id"=> -1))->limit(1);
but that doesn't work.

I checked this and it works for me:
$val = $db->myCollection->find(array(), array('_id' => 1))->sort(array('_id' => -1))->limit(1);
The error in your code is that it should be "_id" and not "id". Also, I hope $db->tweets is a MongoCollection object and you have ensured this. Hope this helps.

Related

Find the position inside this Yii 2 query

I have this following Yii 2 query
$find = People::find()->where(['c_id' => $c_id])->orderBy('totals DESC, id DESC')->all();
So imagine this query was an array. Everything found by this query has an "id" attribute.
Since it's sorted by "totals", I essentially want to return the position in the array where I can find this specific id.
Currently, I'm using this code.
foreach ($find as $t) {
$arr[] = $t->id;
if ($t->id == $id) {
break;
}
}
$key = count($arr);
return $key;
However, this code is vany wayow on a 100k+ result query.
Is there anyway to speed this up?
You could get the result as an array (instead of object) as
$find = People::find()->where(['c_id' => $c_id])
->orderBy('totals DESC, id DESC')
->asArray()
->all();
then you could find your value using array_search()
$my_index = array_search($id,$find);
but for 100k+ you should find using a direct select in db...instead tha looping on php or load all in php and scan with array_search()
To get array from query in YII, you can use queryAll();
$find = People::find()->where(['c_id' => $c_id])->orderBy('totals DESC, id DESC')->queryAll();
OR, another way to convert the object into an array is:
$find = json_decode(json_encode($find), true); // to convert all data into array.
And once you get results in array, you can implement the actual code for your requirement as given below.
You can use array_search() function to get index of your value.
$a=array("a"=>"red","b"=>"green","c"=>"blue");
echo array_search("red",$a);
The array_search() function search an array for a value and returns the key.
Maybe I didn't understand you correctly but I assume that you are trying to detect the index or key for your desired id inside an array returned from an SQL query that is sorted by some other column like total.
So let us fetch records from the database with your query with a little change asArray() like this
$find = People::find()
->where(['c_id' => $c_id])
->orderBy('totals DESC, id DESC')
->asArray()
->all();
in the result, let us assume the People table returns you an array with the following dataset ordered by columns total and id DESC.
[
0 => [
'id' => 2 ,
'c_id'=>2,
'name' => 'John' ,
'age'=>18,
'totals'=>100,
],
1=>[
'id'=>1,
'c_id'=>55,
'name'=>'Bob',
'age'=>20,
'totals'=>80,
],
2=>[
'id'=>3,
'c_id'=>85,
'name'=>'Peter',
'age'=>15,
'totals'=>75,
]
];
Now if you look into \yii\helpers\ArrayHelper you will find ArrayHelper::getColumn().
Let us use this on the array we received from the query, I assume that you are searching $id inside the column id so we will first filter out the id column like below.
$idsArray = ArrayHelper::getColumn($find, 'id');
this will give us the ids in the following sequence which is in the same order as the initial result set.
[2,1,3]
then lets use the built-in php function array_search()
$key=array_search($yourId,$idsArray);
Hope this is what you are looking for.

Undefined offset 0 error in php

I have the following code in of the functions of my controller:
$this->loadModel('Cardetail');
$car_info_oneway= $this->Cardetail->query("Select * from cardetails as c INNER JOIN sellers as s ON c.seller_id=s.id where c.id='$car_id_oneway'");
What I want to do is to read value of one of the columns of the result set in my view. However, every time I get an error "Undefined offset 0." Here is the part of my code in view. :
$count = $car_info_oneway[0]['c']['total_number_of_seats'];
What could be the issue here?
Why are you using query()? You should be using Cake's find() method to retrieve your data using contain to retrieve the Seller data too (you need to make sure your Cardetail and Seller models are correctly associated).
I assume you're just trying to retrieve a single Cardetail record so should be using find('first'):-
$this->loadModel('Cardetail');
$car_info_oneway = $this->Cardetail->find('first', [
'contain' => ['Seller'],
'conditions' => [
'Cardetail.id' => $car_id_oneway
]
]);
When using find('first') the returned array will not be numerically indexed so your $count will be:-
$count = $car_info_oneway['Cardetail']['total_number_of_seats'];
If you run in to issues you can check the returned array using debug($car_info_oneway).

Comparing 2 fields within a Mongo Aggregation Query

I have a collection in my Mongo Database called WorkOrder with 2 fields DateComplete and DateDue. Using those 2 fields I'd like to use the aggregation framework to count the number of 'Late' Work Orders by comparing the two fields. However the research I've found hasn't had any useful ways to format the query so that the 'Late' Work Orders will be filtered through. Does anyone know of a way to format a Mongo DB Aggregation Query (preferably in PHP) that can compare 2 fields in the collection?
EDIT:
An example entry in WorkOrder might look like
_id
some mongo id
DateDue
2014-10-10
DateCompleted
2014-10-12
This entry would want to be filtered through since DateCompleted is greater than DateDue. I didn't know about the $cond operator so I haven't tried anything for that yet.
EDIT:
After trying #BatScream's suggestion with the following query in my PHP script
array(
'$cond' => array(
'if' => array(
'dateDue' => array(
'$lt' => 'dateComplete
)
)
)
)
However the MongoCollection::Aggregate function told me that $cond wasn't a recognized operator.
EDIT: #BatScream's answer seems to work but I wasn't aware of the fact that the group operator doesn't work properly after a $project is applied. I was hoping to be able to group these document on another field cID, is that possible?
The below aggregation pipeline would give you the result, considering your fields are of ISODate type. If not i suggest you to store them as ISODate type and not Strings.
db.collection.aggregate([
{$project:{"isLateWorkOrder":{$cond:[{$lt:["$dateDue","$dateCompleted"]},
true,false]}}},
{$match:{"isLateWorkOrder":true}},
{$group:{"_id":null,"lateWorkOrders":{$sum:1}}},
{$project:{"_id":0,"lateWorkOrders":1}}
])
The PHP syntax should look similar to,
$projA = array("isLateWorkOrder" =>
array("$cond" =>
array(array("$lt" =>
array("$dateDue","$dateCompleted")),
true,false)))
$matchA = array("isLateWorkOrder" => true)
$grp = array("_id" => null,"lateWorkOrders" => array("$sum" => 1))
$projB = array("_id" => 0,"lateWorkOrders" => 1)
$pipeline = array($projA,$matchA,$grp,$projB);
$someCol -> aggregate($pipeline)
or, simply using the count function:
db.collection.count({$where:"this.dateDue < this.dateCompleted"})

MongoDb delete by parametr

I try NoSQL.
I know how delete by id
$criteria = array(
'_id' => new MongoId('5277aeb6b28fada80a00002b'),
);
$users->remove($criteria);
but how to delete if you new for example value, like "name"="John"
You have to do absolutely the same thing as you have done with _id field:
$users->remove(array(
'name' => 'John'
));
You can always look at mongodb php documentation to find how to transform mongodb shell code to php.
I don't now how it is represented in PHP, but in Scala you would do something like this:
val criteria = MongoDBObject("name" -> "John")
coll.remove(criteria)

find by column name cakePHP

Hello I have been trying to understand how to get data from model by the name of field. I am using cakePHP, and I need to retreive a column's data from a table. The syntax is
> "select name from permissions"
So I tried to find out on book.cakephp.org, so I got the field function, but that only gives me the first value, while I have more than one values for this.
I tried do a
$this->Model->find(array('fields'=>'Model.fieldName'));
but I understood that the syntax itself is flawed.
Can somebody let me know what is the method to query based on column name.
$this->Model->find(array('fields'=>'Model.fieldName'))
You forgot the array function. Also:
$this->Model->find(array('fields'=>array('Model.fieldName')))
will work.
findAllBy will find all records based on the field name.
$this->Model->findAllBy<fieldName>(string $value, array $fields, array $order, int $limit, int $page, int $recursive);
For eaxample:
$this->Permission->findAllByName('Some Name');
http://book.cakephp.org/2.0/en/models/retrieving-your-data.html#findallby
Found it... hope it will help someone.
$workshop_lists = ClassRegistry::init('Workshop')->find('all',array(
'fields'=>array('user_id', 'title')
),
array(
'conditions' => array('user_id' => $this->Auth->user('id')),
'group' => 'Workshop.user_id',
'order' => 'posted DESC',
));
There is no way you can query out based on column name using one of the cake methods. You have to use the query method.
Syntax: $this->Model->('Select columnname from table');
$this->Model->find('all',array('fields'=>array('Model.fieldName')))
it works for me everytime.
If I understood well and you want not only 1 value but the whole values in the column 'name' from the table 'permissions'. In that case you could use:
$this->Model->find('list',$params);
(see explanation for 'find' here)
for the '$params' part you would use:
$params=array('fields'=>array('name'));
or putting all in a single line:
$arrayOfNames= $this->Model->find('list',array('fields'=>array('name')));
This will give you an array '$arrayOfNames' wich key is the 'id' (primary key) in 'permissions' table and wich value is the corresponding name in the field 'name' from the same table. This is the array would be something like:
'id'=>'name'
[23]=>'name1'
[28]=>'name2'
[29]=>'name3'
............
very much like I think you want. Hope it helps.
$this->Model->find('list', ['valueField' => 'fieldName']);

Categories