Can't query with mongodb-1.1.x php driver - php

I just updated mongodb to version 3.2 and updated my php driver to the latest. Here is the docs.
They changed almost everything with this new driver and there is not enough documentation I think. I couldn't find how to count, limit and sort the data with php as before.
I found sort method in mongodb website, but there is nothing about it in php docs and source code.
Is there anyone who has dealt with this new driver? How can I sort and limit my query results with php?

To use the new mongo php driver, unlike the old version which just requires mongo.so or mongo.dll to be installed, you will need to get the package mongodb/mongodb through composer:
composer.phar require "mongodb/mongodb=^1.0.0#beta"
Then you can use this example for an initial try:
<?php
require 'vendor/autoload.php'; // include Composer goodies
$manager = new MongoDB\Driver\Manager("mongodb://localhost:27017");
$collection = new MongoDB\Collection($manager, "db_name.collection_name");
$result = $collection->find( [ 'id' => '1', 'name' => 'John' ] );
foreach ($result as $entry)
{
echo $entry->id, ': ', $entry->name, "\n";
}
?>
More examples can be found in https://github.com/mongodb/mongo-php-library/blob/master/examples/bulkwrite.php and https://github.com/mongodb/mongo-php-library/blob/master/examples/write.php
The count method can be found in https://github.com/mongodb/mongo-php-library/blob/master/src/Collection.php
sort and limit are the options to add to find() method:
$options = [
'sort' => ['id' => 1],
'limit' => 5
];
$result = $collection->find( [ 'id' => '1', 'name' => 'John' ], $options );

Related

Using like operator in Elasticserch PHP

I'm using elasticsearch version 8.4 with PHP. I created the index articles e and he has all the registers that are present in the correspondent table in database.
I need to do a search with elasticsearch that return the same results that a SQL search would do.
SELECT *
FROM articles
WHERE title LIKE '%Document%'
However, the results are not the same using elasticsearch php. The php code follows:
<?php
require_once "vendor/autoload.php";
use Elastic\Elasticsearch\ClientBuilder;
$client = ClientBuilder::create()
->setHosts(['localhost:9200'])
->setBasicAuthentication('elastic','secret')
->build();
$params = [
'index' => 'articles',
'from' => 0,
'size' => 5000,
'body' => [
'query' => [
'match' => [
'title' => 'Document'
]
]
]
];
if (!empty($results['hits']['hits']))
{
echo "<pre>";
print_r($results['hits']['hits']);
echo "</pre>";
}
I tried 'wildcards' and 'regexp' instead of 'match', but it not worked.
I read these pages of docs to help in this case:
https://www.elastic.co/guide/en/elasticsearch/reference/current/sql-like-rlike-operators.html#sql-like-operator https://www.elastic.co/guide/en/elasticsearch/client/php-api/8.4/search_operations.html
Is there any to reproduce this elasticsearch php code return same results of sql query executed directly in database?

Get error 'MongoResultException' when use aggregate in mongoDB

When i use aggregatein PHP, i get error:
MongoResultException: localhost:27017: The 'cursor' option is
required, except for aggregate with the explain argument
I use mongoDB 3.6 and PHP 5.6
Please see the photo
My Code:
$dbconn = new MongoClient();
$c = $dbconn->selectDB("test")->selectCollection("users");
$ops = array(
array(
'$lookup' => array(
'from' => 'news',
'localField' => '_id',
'foreignField' => 'user_id',
'as' => 'user_docs'
)
)
);
$results = $c->aggregate($ops);
var_dump($results);
For other people who may run into the same problem, here is the solution.
The aggregator command was modified in version 3.6, as indicated in the documentation:
Changed in version 3.4: MongoDB 3.6 removes the use of aggregate command without the cursor option unless the command includes the explain option. Unless you include the explain option, you must specify the cursor option.
In Mongo, you could just add the cursor option without specifying any parameter, as specified in the documentation:
cursor: {}
In PHP, you would need to specify the option like this, new stdClass()corresponding to an empty object '{}' in Mongo :
$results = $c->aggregate($ops, ['cursor' => new \stdClass()]);
Here's how to do it for your example :
$dbconn = new MongoClient();
$c = $dbconn->selectDB("test")->selectCollection("users");
$ops = array(
array(
'$lookup' => array(
'from' => 'news',
'localField' => '_id',
'foreignField' => 'user_id',
'as' => 'user_docs'
)
)
);
$results = $c->aggregate($ops, ['cursor' => new \stdClass()]);
var_dump($results);
If you want to take advantage of calling 'cursor' to add parameters, such as batchSize, you can do it like this :
$results = $c->aggregate($ops, ['cursor' => ['batchSize' => 200]]);
All the parameters are listed in the documentation page linked above.

Latest Mongodb search collection

There are currently many conflicting posts regarding mongodb and php due to the driver version. I am using driver 1.2.7, php 5.6 and the latest mongodb on XAMPP
This is my current code:
$filter = [ 'userID' => $myUserId, 'isSold' => true];
$cmdOne = new MongoDB\Driver\Command([
'distinct' => 'collectionNameHere',
'key' => 'productID',
'query' => $filter
]);
$cursorOne = $connection->executeCommand('DatabaseNameHere', $cmdOne);
$products = current($cursorOne->toArray())->values;
Is there a way to find non-distinct results?
This does not work due to the different mongoDb driver:
MongoDB search in collection
You've to use executeQuery with query filter and projection
$filter = [ 'userID' => $myUserId, 'isSold' => true];
$projection = ['projection' => ['productID' => 1]];
$query = new MongoDB\Driver\Query($filter, $projection);
$cursor = $connection->executeQuery('DatabaseNameHere.CollectionNameHere', $query);

How to use geoNear with the current PHP MongoDB Driver?

I'm currently working with the current PHP MongoDB\Driver .
I need to use an geoNear query to fetch points from my current location. The required 2dsphere index is already set, the query works in the console and delivers multiple results:
db.runCommand({geoNear: 'pois', near: [ 52.264633, 6.12485 ], spherical: true, maxDistance: 1000, distanceField: 'distance'})
Since the previous methods are deprecated, I can't use the old aggregate functions.
I'm now trying to find the right way to build the query I need with the current Query or Command classes.
What I've tried is the following:
$query = array(
'geoNear' => 'pois',
"near" => array(
52.264633,
6.12485
),
"spherical" => true,
"maxDistance" => 1000,
"distanceField" => "distance"
);
$cmd = new MongoDB\Driver\Command($query);
$returnCursor = $this->conn->executeCommand("database.pois", $cmd);
$arrReturn = $returnCursor->toArray();
return $arrReturn;
If I use this, I will return this Runtime Error:
"exception": [
{
"type": "MongoDB\\Driver\\Exception\\RuntimeException",
"code": 18,
"message": "Failed to decode document from the server."
}
]"
I couldn't find a solution for my case and also I couldn't find more information to this error.
If I change the Command up to a Query, the execution doesn't fail, but there are no results.
My mongodb is on the version 3.2, my PHP version is PHP Version 7.0.16-4+deb.sury.org~trusty+1 and the mongodb Exension is version 1.2.3
You can use the aggregate in the following way with new driver.
$pipeline = array(array(
'$geoNear'=> array(
'near' => array(
52.264633,
6.12485
),
'spherical' => true,
'maxDistance' => 1000,
'distanceField' => "distance"
)));
$cmd = new \MongoDB\Driver\Command([
'aggregate' => 'pois',
'pipeline' => $pipeline
]);
$returnCursor = $this->conn->executeCommand("database", $cmd);
$arrReturn = $returnCursor->toArray();
There is also a Library from Mongo that expands the default functionality of the driver to make it a little more user friendly
but as its not built into the php website its easy to miss
MongoDB\Collection::aggregate($pipeline, $options)
where
$pipeline = array(array(
'$geoNear'=> array(
'near' => array(
52.264633,
6.12485
),
'spherical' => true,
'maxDistance' => 1000,
'distanceField' => "distance"
)
));

HHVM MongoDb aggregation seems like it doesn't work

I have some php script running on hhvm
I'm trying to get max value of numeric field from my collection in MongoDB 3.2
Here is my aggregation pipeline
$mongo = new \MongoDB\Driver\Manager(MONGODB_HOST);
$myCollection = new \MongoDB\Collection($mongo, "mydb.mycollection");
$pipeline = [
[
'$group' => [
'_id' => 'group_field',
'slId' => ['$max' => '$saleId']
],
]
];
$doc = $myCollection->aggregate($pipeline);
This pipeline perfectly works in mongo shell, but from php $doc contains all documents from my collection and no $group is applied to them
Maybe someone can help me with that?
The aggregation operation is returning all documents from your collection since you are specifying a constant value for the group by key, the string group_field. You need to prefix the group field with the $ character in your _id key value. So for example if your group by key is the name field, you can rewrite the aggregation pipeline as
$mongo = new \MongoDB\Driver\Manager(MONGODB_HOST);
$myCollection = new \MongoDB\Collection($mongo, "mydb.mycollection");
$group_field = '$name';
$pipeline = [
[
'$group' => [
'_id' => $group_field,
'slId' => ['$max' => '$saleId']
],
]
];
$doc = $myCollection->aggregate($pipeline);
Thanks to chridam's answer up here.
I don't know, but maybe this is some kind of magic
So, chridam's answer helped me with $group, so finally my results were grouped by $group_field. But slId still wasn't there. So, here is what i did and it helped:
$f = '$group_field';
$sl = ['$max' => '$saleId'];
$pipeline = array(
array(
'$group' => array(
'_id' => $f,
'slId' => $sl
),
)
);

Categories