i want to make query like this with cakephp:
WHERE text LIKE '%keyword%'
AND
(
(text LIKE '%something%')
OR (text LIKE '%something%')
OR (...)
)
AND
(
(text LIKE '%other%')
OR (text LIKE '%other%')
OR (...)
)
NOT
(
(text LIKE '%dont include%')
OR (text LIKE '%dont include%')
OR (...)
)
this is my code for $conditions:
$conditions = array
(
'Tweet.text LIKE' => '%keyword%',
'AND' => array(
array(
'OR' => array(
// topic
array('Tweet.text LIKE' => '%something%'),
array('Tweet.text LIKE' => '%something%')
)
),
array(
'OR' => array(
// sentiment
array('Tweet.text LIKE' => '%other%'),
array('Tweet.text LIKE' => '%other%')
)
)
),
'NOT' => array(
array('Tweet.text LIKE' => '%dont include%'),
array('Tweet.text LIKE' => '%dont include%')
)
);
i am displaying the result with Debugger::dump() method, and the result is just using the last 'OR' condition, not both 'OR' conditions:
array(
'Tweet.text LIKE' => '%keyword%',
'OR' => array(
(int) 0 => array(
'Tweet.text LIKE' => '%other%'
),
(int) 1 => array(
'Tweet.text LIKE' => '%other%'
)
),
'NOT' => array(
(int) 0 => array(
'Tweet.text LIKE' => '%dont include%'
),
(int) 1 => array(
'Tweet.text LIKE' => '%dont include%'
)
)
)
My question is, how do I make a query such that use both 'OR' condition?
Pls reply as soon as possible.. Thanks in advance :)
Try the following:
$conditions = array(
'Tweet.text LIKE' => '%aa%', //implied and
array( //implied and
'or' => array(
array('Tweet.text LIKE' => '%11%'),
array('Tweet.text LIKE' => '%22%'),
array('Tweet.text LIKE' => '%33%'),
...
)
),
array( //implied and
'or' => array(
array('Tweet.text LIKE' => '%123%'),
array('Tweet.text LIKE' => '%456%'),
array('Tweet.text LIKE' => '%789%'),
...
)
)
'not' => array(
'or' => array(
array('Tweet.text LIKE' => '%x%'),
array('Tweet.text LIKE' => '%y%'),
array('Tweet.text LIKE' => '%z%'),
...
)
)
)
would be
text LIKE aa
AND ( either 11, 22, 33 )
AND (either 123, 456, 789)
BUT NOT (x || y || z)`
Any array that does not specify or, and or not is and. No need to specify it manually.
Related
I'm trying to join 3 tables using cakephp but I don't understand why when I execute my query there is the result of the main tables without the attributes from the other 2 tables . this is my php code :
$flightSchedule = $this->FlightSchedules->find('all', array(
'join' => array(
array(
'table' => 'WeeklySchedules',
'alias' => 'ws',
'type' => 'INNER',
'conditions' => array(
'FlightSchedules.code = ws.flight_plan_code'
),
array(
'table' => 'Structures',
'alias' => 's',
'type' => 'LEFT',
'conditions' => array(
'FlightSchedules.code = s.flight_plan_code',
)),
)),
'conditions' => array(
'FlightSchedules.plane_code' => 'xxx'
),
));
the result of this is always the FlightSchedules record without the join of the other tables . Any ideas how to fix this ?
use "fields" for display the data of an associated table .
$flightSchedule = $this->FlightSchedules->find('all', array(
'join' => array(
array(
'table' => 'WeeklySchedules',
'alias' => 'ws',
'type' => 'INNER',
'conditions' => array(
'FlightSchedules.code = ws.flight_plan_code'
),
array(
'table' => 'Structures',
'alias' => 's',
'type' => 'LEFT',
'conditions' => array(
'FlightSchedules.code = s.flight_plan_code',
)),
)),
'conditions' => array(
'FlightSchedules.plane_code' => 'xxx'
),
'fields'=>'FlightSchedules.*,ws.*,s.*'
));
Add this in after condition array
'fields' => 'FlightSchedules.*, WeeklySchedules.*, Structures.*'
I am still learning wordpress and trying to perform a query of posts with WP_Query, meta_query to be precise, the thing is after trying different possible ways and finding out that I can't nest arrays with relations I dont know if the next possible way is to make a sql query directly.
To better explain what I would like to do, the next array hopefully will help:
'meta_query' => array(
'relation' => 'AND',
array(
'key' => 'Meta_geo',
'value' => '46',
'compare' => '=',
),
array(
'key' => 'Meta_dest',
'value' => 'si',
'compare' => '=',
),
array(
'relation' => 'OR',
array(
array(
'key' => 'Meta_1',
'value' => '10',
'compare' => '<=',
),
array(
'key' => 'Meta_1',
'value' => '30',
'compare' => '>=',
)
),
array(
'relation' => 'OR',
array(
'key' => 'Meta_1',
'value' => '',
'compare' => '=',
),
array(
'key' => 'Meta_1',
'value' => '',
'compare' => '=',
)
)
)
),
many Thanks for the time, if there are an expertet who can give me a hint I will be grateful.
Sorry for my english.
Based on what you have above the below is the closest your are going to get...
'meta_query' => array(
'relation' => 'OR',
array(
'key' => 'Meta_geo',
'value' => '46',
'compare' => '=',
),
array(
'key' => 'Meta_dest',
'value' => 'si',
'compare' => '=',
),
array(
'key' => 'Meta_1',
'value' => array('10','11','12' etc),
'compare' => 'IN',
),
)
This will leave you a little sorting out to do however. This can be done with a loop and as you normally display the results of a query using the loop you can use that.
e.g.
while ( $my_query->have_posts() ) : $my_query->the_post();
$metavalue = get_post_meta($post->ID, 'meta_geo', true);
$metavalue = get_post_meta($post->ID, 'meta_dist', true);// if there are a lot of conds, use get_post_meta($post->ID) to return object of value arrays
if($metavalue == 46 && ): //proceed
//html here!
endif;
endwhile;
I've got the below code which will not 'work'... How can I go about excluding multiple items from the SQL query? I've tried many different combinations without any luck :(
$this->autoLayout = false;
$this->set('songs', $this->CcFile->find('all', array(
'fields' => array(
'track_title',
'artist_name',
'lptime',
'id'
),
'conditions' => array(
'AND' => array(
'NOT' => array(
'artist_name' => 'Jam FM Bed',
),
'NOT' => array(
'artist_name' => 'Airtime Show Recorder',
),
'NOT' => array(
'artist_name' => 'Jam FM Jingles',
),
'NOT' => array(
'artist_name' => 'Kent Scout Jingles',
),
),
),
'order' => array(
'lptime' => 'desc nulls last',
'artist_name' => 'asc'
)
)));
Try that:
'NOT' => array(
'artist_name' => array(
'Jam FM Bed',
'Airtime Show Recorder',
// ...
)
)
or
'artist_name NOT IN' => array(
'Jam FM Bed',
'Airtime Show Recorder',
// ...
)
Try this
fixed code
$this->autoLayout = false;
$this->set('songs', $this->CcFile->find('all', array(
'fields' => array(
'track_title',
'artist_name',
'lptime',
'id'
),
'conditions' => array(
'NOT' => array(
'artist_name' => Array(
'Jam FM Bed',
'Airtime Show Recorder',
'Jam FM Jingles',
'Kent Scout Jingles')
),
),
'order' => array(
'lptime' => 'desc nulls last',
'artist_name' => 'asc'
)
)));
This code:
$conditions = array(
'fields' => array(
'User.id'
),
'conditions' => array(
'AND' => array(
'UsersProblem.problem_id' => 38,
'UsersProblem.problem_id' => 34,
),
),
'recursive' => -1
);
$conditions['joins'][] = array(
'table' => 'users_problems',
'alias' => 'UsersProblem',
'type' => 'INNER',
'conditions' => array(
'User.id = UsersProblem.user_id',
));
Is transforming to this SQL query:
SELECT `User`.`id`
FROM `lawyers`.`users`
AS `User`
INNER JOIN `lawyers`.`users_problems`
AS `UsersProblem`
ON (`User`.`id` = `UsersProblem`.`user_id`)
WHERE `UsersProblem`.`problem_id` = 34
Where is AND UsersProblem.problem_id = 38"?
How to create correct find condition to get users with some list of problems? Which are linked as many to many relationship.
Using $this->Problem->find is not possible, beause I need to use 2 joins: users_problems and users_practices. And use for them AND condition, like this:
'AND' => array(
'UsersProblem.problem_id' => 38,
'UsersProblem.problem_id' => 34,
'UsersPractices.practice_id' => 1,
'UsersPractices.practice_id' => 2,
),
You're overwriting 'UsersProblem.problem_id'. Just think about it like the array it is. CakePHP is just using the PHP array structure to do these finds, and that means it follows array rules. But to get around that in cakephp, you're supposed to use a two dimensional array
Like this:
'AND' => array(
array('UsersProblem.problem_id' => 38),
array('UsersProblem.problem_id' => 34)
),
Instead of this:
'AND' => array(
'UsersProblem.problem_id' => 38,
'UsersProblem.problem_id' => 34
),
That way, instead of trying to set the key 'UsersProblem.problem_id' twice, you're making an array that looks like
0 -> array('UsersProblem.problem_id' => 38)
1 -> array('UsersProblem.problem_id' => 34)
And that will work, it's a workaround the CakePHP guys built into the system for this kind of situation.
I think you need to use OR instead of AND:
$conditions = array(
'fields' => array(
'User.id'
),
'conditions' => array(
'OR' => array(
array('UsersProblem.problem_id' => 38),
array('UsersProblem.problem_id' => 34),
),
),
'recursive' => -1
);
You can also roll this up as follows:
$conditions = array(
'fields' => array(
'User.id'
),
'conditions' => array(
'OR' => array(
'UsersProblem.problem_id' => array(34, 38)
),
'recursive' => -1
);
Change your conditions array as shown below:
$options = array(
'fields' => array('User.id'),
'conditions' => array('UsersProblem.problem_id' => array(38,34)),
'recursive' => -1
);
$options['joins'] = array(
array(
'table' => 'users_practices',
'alias' => 'UsersPractices',
'type' => 'INNER',
'conditions' => array(
/CONDITION OF JOIN/
),
array(
'table' => 'users_problems',
'alias' => 'UsersProblem',
'type' => 'INNER',
'conditions' => array(
'User.id = UsersProblem.user_id',
)
);
From User Model:
$this->find('list',$options);
Do not use AND/ OR because they are not optimized for above case.
For reference:
MYSQL OR vs IN performance
and
CakePHP right way to do this (get value from setting's table)
**Try the code for join tables in cakephp.......**
$options = array('joins' => array(
array(
'table' => 'modelname1',
'alias' => 'modelName1',
'type' => 'LEFT',
'foreignKey' => false,
'conditions' => array('modelname1.id = modelname2.mid')
)
),
'fields' => array('modelName1.field1', 'modelName1.field2', 'modelName2.field1', 'modelName2.field2'),
'conditions' => array('modelname.id' => 1, 'modelname2.field1' => ''),
'limit' => 10, 'page' => 1);
$this->modelName2->find($options);
I want to reduce the number of fields returned by cakephp's find('all') but don't know if this is possible.
$this->Group->find('all', $params);
where $params
$params = array(
'conditions' => array(
'Group.featured' => 1,
),
'contain' => array(
'User',
'Class' => array(
'conditions' => array(
'Class.exp IS NOT NULL',
'Class.tb <20',
)
)
)
));
The problem is that my Class table has many columns that i don't need and that take a long time to load, so i would line to only select 5 fields.
Can this be done in Cakephp or am i better off writing a regular query?
something like
$params = array(
'conditions' => array(
'Group.featured' => 1,
),
'contain' => array(
'User',
'Class.a',
'Class.b',
'Class.exp',
'Class.tb',
'Class' => array(
'conditions' => array(
'Class.exp IS NOT NULL',
'Class.tb <20',
)
)
)
));
Thank you
That's what the fields parameter is for.
$params = array(
...
'contain' => array(
'Class' => array(
'conditions' => array(
'Class.exp IS NOT NULL',
'Class.tb <20',
),
'fields' => array('a', 'b')
)
)
);