mongodb find query with OR and AND - php

I have the following if query.
if(($version[0] == 1)||($version[1] > 6)||($version[2]>=14 && $version[1] == 6))
{
echo "true";
}
Now I want this query translated to a mongodb query.
In the mongo collection I have the following entry:
{
"main_version" : 0,
"sub_version" : 6,
"build_version" : 14,
"module" : "Co2",
"active" : 1
}
When I try the following query I get a mongo error.
$where = array('$or' => array(
array('main_version'=> (int)$version[0]),
array('sub_version'=> array('$gt'=> (int)$version[1])),
array('$and' => array('build_version' => array('$gte'=> (int)$version[2])),
array('sub_version' => (int)$version[1]),
),
array('active'=> 1),
),
);
Error: Can't canonicalize query: BadValue and needs an array'
Does anybody know how to solve this query?

Well, worked in php 6 years back but I think your $and operator should accept array of queries,
something like array('$and' => array(array('build_version' => array('$gte'=> (int)$version[2])), array('sub_version' => (int)$version[1]))
'and' accepts array as you are doing for 'or' opeartor, here you are passing the query instead of array.

Yes, the extra array was the sollution. tx

Related

CakePHP multiple OR conditions

Im looking to create a simple query but i can't seem to figure out how to do it using Cakes conditions (cake 1.3), what im looking to do is quite simple, in SQL its just
SELECT * FROM table WHERE firstvalue != '' OR secondvalue != ''
So basically only return row if there is a value in either firstvalue or second value.
At the moment i have;
$conditions = array(
"NOT" => array(
'firstvalue' => ''
)
);
This works fine for the first value, but if i try and add anything to it, it still only returns the results for the firstvalue
Two ways to go about this:
$conditions = array(
'OR' => array(
array('NOT' => array('firstvalue' => '')),
array('NOT' => array('secondvalue' => ''))
)
);
Or, take advantage of the fact that "NOT a OR NOT b" == "NOT (a AND b)":
$conditions = array(
'NOT' => array(
array('firstvalue' => ''),
array('secondvalue' => '')
)
);
To add multiple fields in OR condition, you have to write the fields in array.
Like,
$conditions = array(
"OR" => array(
"NOT"=>array('firstvalue' => ''),
array('secondvalue'='')
)
)
);
I hope it will work for you.

Find all documents in mongodb

I want to display all documents (select *) with sub-documents in PHP.
I know how to query all find() but I have no idea how to do it when I have sub-documents. I don't know if there's something like find() or I need to make loops fo every sub-documents that I'd have.
This would be the code
$mongodatabase->insertOne(
['name' => 'Alex',
'surname' => 'Turner',
'country' => 'England',
'birth' => array(
'day' => 6,
'month' => 'january',
'year' => 1986
),
]);
Something easy, just to learn. When I try a var_dump of day I get Undefined index and NULL.
$client = new MongoDB\client;
$db = $client->database;
$mongodatabase = $db->document;
$document = $mongodatabase->find();
foreach ($document as $doc) {
var_dump($doc->day);
}
However, I'd like to query all.
Use $exists - It helps us in identifying the elements which are not empty
db.collection_name.find({
"birth.day" : {
$exists : true
}
});
If you need to check not null and empty, then we need to use $type together with $exists, $type can be passed with different values and 10 is for null check
db.collection_name.find({
"birth.day" : {
$not : { $type : 10 },
$exists : true
}
});
when u find the exactly data from mongoldb u can use the shelter to limit the field
eg:
db.xxxxx.find(
{'status':'DELIVRD'}
);

CakePHP 2 .10.0 "OR" condition is not working

I am using Cakephp 2.10.0. While working with find condition, I am facing a strange issues LIKE "OR" condition convert automatically to "AND" e.g
I am making find condition like:
$this->{$this->leadCall}->find('list', array('conditions'=>array($this->leadCall.'.future_call !=' => date('m/d/Y'), 'or' => array($this->leadCall.'.future_call !=' => '')),'fields' => array('lead_id')));
It results
SELECT `LeadCall`.`id`, `LeadCall`.`lead_id` FROM `zindagihomes`.`lead_calls` AS `LeadCall` WHERE `LeadCall`.`future_call` != '11/19/2017' AND `LeadCall`.`future_call` != ''
And I want query something like this
SELECT `LeadCall`.`id`, `LeadCall`.`lead_id` FROM `zindagihomes`.`lead_calls` AS `LeadCall` WHERE `LeadCall`.`future_call` != '11/19/2017' OR `LeadCall`.`future_call` != ''
I got my mistake. It was due wrong array formation.
<pre>
$conditions = array(
'OR' => array(
$this->leadCall.'.future_call !=' => date('m/d/Y'),
$this->leadCall.'.future_call !=' => ''
)
);
$futureCall = $this->{$this->leadCall}->find('list', array('conditions'=>$conditions,'fields' => array('lead_id')));
</pre>
it is working fine as expected.

how to use $bit operator to query in mongodb with php

i have a document like bellow, now i will to figure out which element in friendsR whose readable & 2 is grater than 0. anyone here can help me? thank you.
[code]
$doc = array('friendsR' => array(
array('friend_id'=>100, 'readable' => 7, 'bridge'=>5),
array('friend_id'=>100, 'readable' => 7, 'bridge'=>6),
array('friend_id'=>100, 'readable' => 7, 'bridge'=>7))
);
datamodel()->insert($doc);
$macher = array('$bit' => array( 'friendsR.$.readable' => array('and'=>2) ));
$cursor = datamodel()->find($macher);
[/code]
The $bit operator is an "update operator", so it is used to change values and not query them.
If you need this sort of query you need a JavaScript evaluation such as $where:
For a document that looks like this in the shell:
{
"friendsR": [
{ 'friend_id': 100, 'readable': 7, 'bridge': 5 },
{ 'friend_id': 100, 'readable': 7, 'bridge': 6 },
{ 'friend_id': 100, 'readable': 7, 'bridge': 7 }
]
}
To just find documents that have a matching element you would do this:
$macher = array(
'$where' => new MongoCode("function(){
return this.friendsR.some(function(x) {
return ( x.readable & 2 ) > 0
})
}")
);
To actually return "which elements" matched you would again have to do something like this with mapReduce. It will "mark" which items in the array met the condition and only return documents where at least one array member that matches.
$map = new MongoCode("function(){
this.friendsR.forEach(function(friend) {
friend.macthed = ( ( friend.readable & 2 ) > 0 );
});
if ( this.friendsR.some(function(x) { return x.matched }) )
emit( this._id, this );
}");
$reduce = new MongoCode("function(){}");
$result = $db->command(array(
"mapreduce" => "collection_name",
"map" => $map,
"reduce" => $reduce,
"out" => array( "inline" => 1 )
));
There are no built in operators for bitwise evaluation so JavaScript is your only option where it is available.
Note that the mapReduce is a command and must be run from a Db object, the result is either returned inline as shown or output to another collection. This does not return a cursor. See the official documentation on mapReduce for more information.

Count too slow in MongoDB with PHP

I'm trying to check my code, with count lines. But this code works very slow. how can i optimize this code? is there anyway to count?
$find = $conn_stok->distinct("isbn");
for($i=0;$i<=25; $i++) {
$isbn = $find[$i];
$countit= $conn_kit->find(array('isbn'=>$isbn))->count();
if($countit> 0){
echo "ok<br>";
} else {
echo "error<br>";
}
}
Looks like you are trying to do a simple count(*) group by in the old SQL speak. In MongoDB you would use the aggregation framework to have the database do the work for you instead of doing it in your code.
Here is what the aggregation framework pipeline would look like:
db.collection.aggregate({$group:{_id:"$isbn", count:{$sum:1}}}
I will let you translate that to PHP if you need help there are plenty of examples available.
It looks like you're trying to count the number of 25 top most ISBNs used, and count how often they have been used. In PHP, you would run the following queries. The first one to find all ISBNs, and the second is an aggregation command to do the grouping.
$find = $conn_stok->distinct( 'isbn' );
$aggr = $conn_kit->aggregate(
// find all ISBNs
array( '$match' => array( 'isbn' => array( '$in' => $find ) ) ),
// group those
array( '$group' => array( '_id' => '$isbn', count => array( '$sum' => 1 ) ) ),
// sort by the count
array( '$sort' => array( 'count' => 1 ) ),
// limit to the first 25 items (ie, the 25 most used ISBNs)
array( '$limit' => 25 ),
)
(You're a bit vague as to what $conn_stok and $conn_kit contain and what you want as answer. If you can update your question with that, I can update the answer).

Categories