Update database field with BETWEEN operator using CakePHP and MongoDB - mongodb

How to update all fields affected in MongoDB using cakephp. Say I have queried the Start and End Time. I want to update all the fields affected BETWEEN those time of an specific user.
<?php
$stime = $this->data["User"]["sTime"]; //$stime = "2:29 PM";
$etime = $this->data["User"]["eTime"]; //$eTime = "3:40 PM";
$user = $this->data["User"]["affected_user"];
?>
All the fields within the start and end time will be affected. I would like to update a field called status and set it to "1". Thanks

You can use the updateAll() statement to update multiple fields like.
<?php
// first of all convert the start time and end time in proper date format the use the statement like bellow.
$this->ModelName->updateAll(array('status' => 1), array('time >=' => $stime, 'time <' => $etime));
?>
If you want to update multiple fields then you can specify like status in the same array. For more information checkout the updateAll() documentation on the cakephp site.

Related

update a field with the value of other field

How can I update a field with the value of other field?
For example, I want to update the field updated_at with the value of the field created_at (it's like cloning fields)
$dm->createQueryBuilder('MyBundle:MyService')
->update()
->multiple(true)
->field('updated_at')->set(CREATED_AT_ATRIBUTE)
->getQuery()
->execute();
Thanks
Option #1: Application side update
The easiest approach when using Doctrine ODM is to perform the update on the application side. So you fetch all the objects you want to update, make the necessary adjustments and flush them.
$services = $dm->createQueryBuilder('MyBundle:MyService')
->getQuery()
->execute();
foreach ($services as $service) {
$service->setUpdatedAt($service->getCreatedAt());
}
$db->flush();
$services represents the mongo cursor, which will fetch the documents as you iterate. You can set eagerCursor to true if you want to fetch all the documents from the collection at once.
Option #2: Database side update
You can also perform the update directly on the database itself. To do so however, you'll need to create the query yourself as the query builder doesn't support this functionality.
// Get MongoDB instance from DocumentManager
$mongo = $dm->getDocumentDatabase('Fully/Qualified/Class/Name')
->getMongoDB();
// Iterate over the collection and update each document
$mongo->execute('
db.MyServiceCollection.find().forEach(function (item) {
db.MyServiceCollection.update(
{_id: item._id},
{$set: {updated_at: item.created_at}}
);
});
');
The function used in forEach is just a regular javascript function, so you can insert some more logic in there if you need more control over what you update.

How to sort elasticsearch results by distance?

I'm using elasticabundle for symfony2 and I want to sort results I'm seeking by distance
I'm new to elasticsearch and I don't know how I can start
the query I'm using :
$c = $this->container->get('fos_elastica.finder.cities_index.cities');
$nameQuery = new \Elastica\Query\Match();
$nameQuery->setFieldQuery('tokens', $city);
$nameQuery->setSort(array("distance" => "asc"));// I want to achieve this
Thanks for your time
here is what I did following the example as provided by Dimitris Tsarouhas
The following setup allows to filter by keyword, order by id, and add all sort of other filtering using the $boolQuery ->addMust($yourfilter) formula.
We fetch the keyword as posted by a form. This is $data['query'] and by default we use it to perform a _all search, thus searching throughout all the fields listed in our config.yml file. To perform this search, we use the QueryString object, as this allows us to use wildcards.
We then look if exists the variable $data['status'], which comes through a dropdown select box (please note the use of strtolower(), without which the query wouldn't work - either that or you set up your own case-insensitive analyzer). If so, we use it to filter our results.
By default, we also want to narrow down our search and pick up only active users.
$data = $form->getData();
$finder = $this->container->get('fos_elastica.finder.search.user');
$keyword = $data['query'];
$status= $data['status'];
$keywordQuery = new QueryString;
$keywordQuery->setQuery('*' . $keyword . '*');
$query = new Query();
$query->setQuery($keywordQuery);
$query->setSort(array('id' => array('order' => 'asc')));
$boolQuery = new Bool();
$active= new Term();
$active->setTerm('active', true);
$boolQuery ->addMust($active);
if (!empty($status)) {
$statusQuery = new Term();
$statusQuery->setTerm('status', strtolower($status->getName()));
$boolQuery ->addMust($typeQuery);
}
$query->setFilter($boolQuery);
$entities = $finder->find($query);
And of course do not forget to import the necessary libraries:
use
Elastica\Query\QueryString,
Elastica\Query,
Elastica\Filter\Bool,
Elastica\Filter\Term
;
Remember that to be able to perform actions on fields (searching, sorting, etc) these haveto be included in your config.yml. Of course, this would cause the field to be automatically picked up when searching generally onto a certain entity. So, if you need to avoid this, but you still need certain fields to be available to elastica. just define it as showed below:
user:
mappings:
name: ~
surname: ~
status: ~
active: { include_in_all: false }
id: { include_in_all: false }

MongoDB Doctrine ODM change the collection name for a document at run time

I have to create collection for users per each day they register so if I have 5 users and 2 register on 2013-03-02 and 3 have register on 2013-03-03 I will have 2 collections
The user is declare in a YML file with no collection
In the project I do an import via CLI something like this
foreach($arUsers as $key=>$arUser)
{
$collection_name = "day_".$arUser['date'];
$user = new User();
/* Change the collection name to be dynamic */
$OdmMetaData = MeltApplication::getDocumentManager()->getClassMetaData( get_class($user) );
$OdmMetaData->setCollection($collection_name);
$user->setUserId($arUser['user_id']);
$user->setEmail($arUser['email']);
....
$this->getDocumentManager()->persist($user);
$this->getDocumentManager()->flush();
}
Problem is that when I look in the mongoDB I see only one collection with name day_2013-03-03" which is the last date , if I set the MeltApplication::getDocumentManager()->flush(); after the foreach end statement which I should it save all in the first collection 03-02 .
Are there any options to do this , to save them separate?
Thanks
$data = $odm->getClassMetadata('NameEntity');
$data->setCollection($collectionName);
This is the answer.
The only solution was to reinitialized the documentManager

In yii how to find date is greater than current date

I am working in Yii framework. I am having Poll table with fields as-
-pollId
-pollQuestion
-Isactive
-publishDate
-isPublish
when new poll is created,that date get inserted into publishDate field.
e.g.2012-04-04 02:23:45 In this format entry get inserted.
Now i want to check weather this publishDate is smaller than today's date or current date. i.e.publishDate should not be greater than current date.
So how to check this in yii? Please help me
As per normal PHP. Assuming $model is the submitted form and you have assigned (after the form has been submitted) $model->attributes = $_POST['MyModel']
You can then use:
if ($model->publishDate < date('Y-m-d H:i:s')){
// it is smaller
}
Another thing you could look at is using Yii's model validation. You could store the created date (which would be todays date) and then compare that to the publishDate in the form submit:
$model->created = date("Y-m-d H:i:s");
if ($model->validate){
...
}
And in your Poll model:
array('publishDate ','compare','created','operator'=>'<', 'message'=>'Publish Date must be smaller than the current date'),

Using php DateTime object in mysql query

I'm trying to create a query that pulls information about sellers from my database, but only if their store has launched in the last 3 days. The easiest way I can think of to calculate the date for the query is using a new DateTime() object. When I output my code to test it, it's in the proper string for MySQL to query it with, but whenever I try to bind the variable, I get an error. I'm using Zend_Db to query, (PDO adapter)
action:
public function indexAction()
{
$dateMod = new DateTime();
$dateMod->modify('-2 days');
$dateMod->format('Y-m-d H:i:s');
// get sellers initialized in last 3 days
$sellerTable = new Application_Model_DbTable_Sellers();
$select = $sellerTable->select()->setIntegrityCheck(false);
$select->from(array('s' => 'seller'),array('sellerID', 'businessName'));
// select firstName, lastName, picture from user table, and businessName and sellerID from seller table.
$select->join(array('u' => 'user'), 's.userID = u.userID', array('firstName', 'lastName', 'picture'));
$select->where('s.active = 1 AND s.contentApproval = 1 AND s.paymentApproval = 1 AND s.featured = 1');
$select->where('s.launchDate > ?', $dateMod);
$select->order('s.launchDate DESC');
$newSellers = $sellerTable->fetchAll($select);
When I assign $dateMod to the view, it outputs the correct Y-m-d H:i:s format. But when I plug it into the query, I get the following error:
Message: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ') ORDER BY `b`.`launchDate` DESC' at line 2
If I hardcode a value into dateMod in the mysql timestamp format, the query works fine. How can I access just the string value of the timestamp in the DateTime object? getTimestamp returns a unix formatted timestamp, even after assigning a format.
The format() function returns the formatted date, so you need to assign that to a variable for use in the query:
$dateFormatted = $dateMod->format('Y-m-d H:i:s');
$select->where('s.launchDate > ?', $dateFormatted);