Code Monkey home page Code Monkey logo

Comments (10)

jmikola avatar jmikola commented on August 14, 2024
<?php

$m = new MongoDB\Driver\Manager();

try {
    $m->executeCommand('test', new MongoDB\Driver\Command(['drop' => 'foo']));
} catch (MongoDB\Driver\Exception\RuntimeException $e) {
    if ($e->getMessage() !== 'ns not found') {
        throw $e;
    }
}

$bulk = new MongoDB\Driver\BulkWrite;
$bulk->insert(['x' => new MongoDB\BSON\UTCDateTime(10000000)]);
$bulk->insert(['x' => new MongoDB\BSON\UTCDateTime(20000000)]);
$bulk->insert(['x' => new MongoDB\BSON\UTCDateTime(30000000)]);
$m->executeBulkWrite('test.foo', $bulk);

$c = $m->executeQuery('test.foo', new MongoDB\Driver\Query(['x' => ['$lt' => new MongoDB\BSON\UTCDateTime(25000000)]]));
var_dump($c->toArray());

This yields the following output for me:

array(2) {
  [0]=>
  object(stdClass)#9 (2) {
    ["_id"]=>
    object(MongoDB\BSON\ObjectID)#7 (1) {
      ["oid"]=>
      string(24) "56844c606118fd64120c45f1"
    }
    ["x"]=>
    object(MongoDB\BSON\UTCDateTime)#8 (1) {
      ["milliseconds"]=>
      int(10000000)
    }
  }
  [1]=>
  object(stdClass)#12 (2) {
    ["_id"]=>
    object(MongoDB\BSON\ObjectID)#10 (1) {
      ["oid"]=>
      string(24) "56844c606118fd64120c45f2"
    }
    ["x"]=>
    object(MongoDB\BSON\UTCDateTime)#11 (1) {
      ["milliseconds"]=>
      int(20000000)
    }
  }
}

If you're on a 32-bit system, it's possible that the UTCDateTime constructor argument is overflowing and you're not creating the value that you think (var_dump() should be able to tell you). If that's happening, note that the constructor also accepts a string argument (documented here).

from mongo-php-driver.

x88 avatar x88 commented on August 14, 2024

So, I checked querying for other expressions, but nothing expressions in query parameter in mapreduce command not working with this driver.
My helper class:

<?php

class MongoProvider {

    private $_connectionManager = null;

    public function __construct() {
        $connectionUri = $this->getUri();
        $this->_connectionManager = new MongoDB\Driver\Manager($connectionUri);
    }

    private function getUri() {
        $uri = 'mongodb://';
        $connectionConfig = Config::get('database.connections.mongodb');
        if (empty($connectionConfig)) {
            throw new \Exception('Empty MongoDB config');
        }

        if (!empty($connectionConfig['username'])) {
            $uri .= $connectionConfig['username'];
            if (!empty($connectionConfig['password'])) {
                $uri .= ':' . $connectionConfig['password'];
            }
            $uri .= '@';
        }
        if (!empty($connectionConfig['host'])) {
            foreach ($connectionConfig['host'] as $host) {
                $uri .= $host . ':' . $connectionConfig['port'] . ',';
            }
            $uri = rtrim($uri, ',');
        }
        $uri .= '/';
        if (!empty($connectionConfig['database'])) {
            $uri .= $connectionConfig['database'];
        }
        if (!empty($connectionConfig['options'])) {
            $uri .= '?';
            foreach ($connectionConfig['options'] as $optionName => $optionValue) {
                $uri .= $optionName . '=' . $optionValue . ',';
            }
            $uri = rtrim($uri, ',');
        }
        return $uri;
    }

    public function mapReduce($collection, $map, $reduce, $finalize, $query = [], $sort = []) {        

        $q = new MongoDB\Driver\Command([
            'mapreduce' => $collection,
            'map' => $map,
            'reduce' => $reduce,
            'finalize' => $finalize,
            'query' => new MongoDB\Driver\Query($query),
            'sort' => $sort,
            'out' => ['inline' => 1]
        ]);
        $response = $this->_connectionManager->executeCommand('adsystem', $q);
        if (!empty($response)) {
            $result = (array)$response->toArray()[0];
        } else {
            return false;
        }
        if ($result['ok'] == 0) {
            echo $result['errmsg'];
            return false;
        } else {
            return $result['results'];
        }
    }

}

Checking function:

        $query = [];
        // 20 Dec 2015
        $query['val']['$gt'] = 50; 
        /*
         * Nothing working
         * $query['val'] = 18;
         * $query[''] = new \MongoDB\BSON\UTCDatetime(1450569600000);         
         */
        $mgo = new \MongoProvider();
        $map = 'function () { emit(this.date, 1); }';
        $reduce = 'function reduce(key, values) { return values[0]; }';
        $finalize = 'function finalize(key, reduced) { return reduced; }';
        $sort = ['hour' => 1];
        $data = $mgo->mapReduce('testmap', $map, $reduce, $finalize, $query, $sort);
        foreach ($data as $resultEntry) {
            echo $resultEntry->_id->toDateTime()->format('d M Y') . "<br>";
        } 

Data

{
  "_id" : 1,
  "date" : ISODate("2015-12-20T00:00:00Z"),
  "val" : 32
},
{
  "_id" : 2,
  "date" : ISODate("2015-12-20T00:00:00Z"),
  "val" : 21
},
{
  "_id" : 3,
  "date" : ISODate("2015-12-21T00:00:00Z"),
  "val" : 53
},
{
  "_id" : 4,
  "date" : ISODate("2015-12-21T00:00:00Z"),
  "val" : 58
},
{
  "_id" : 5,
  "date" : ISODate("2015-12-22T00:00:00Z"),
  "val" : 86
},
{
  "_id" : 6,
  "date" : ISODate("2015-12-22T00:00:00Z"),
  "val" : 18
}

If I try to use external tool, query already working:
screen

from mongo-php-driver.

 avatar commented on August 14, 2024

I am having the same issue like @x88. Query has no result with your transfered example @jmikola. Any other suggestions here?

from mongo-php-driver.

x88 avatar x88 commented on August 14, 2024

@varakh I created issue on Jira https://jira.mongodb.org/browse/PHPC-551

from mongo-php-driver.

jmikola avatar jmikola commented on August 14, 2024

Sorry, I just realized that you guys were including a MongoDB\Driver\Query object in the mapReduce command document. The Query object should only be used for Manager::executeQuery() and Server::executeQuery(), as it consists of a filter and additional options (e.g. projections, sort, limit).

The mapReduce command expects its "query" option to be a BSON document, which is analogous to the first argument you'd provide to the Query constructor.

from mongo-php-driver.

jmikola avatar jmikola commented on August 14, 2024

Closing this and PHPC-551, as I believe the response above should clarify things and help you fix the code in question. If not, feel free to follow up.

from mongo-php-driver.

renannprado avatar renannprado commented on August 14, 2024

I can't make query either. The json that is being generated is not valid to query Mongo, I made changes to generate a correct json and now everything works. Is this a bug or correct behavior and I am misusing the lib?
Edit:
Even with my workaround, it doesn't work.
I thought it worked because it worked within MongoClient, same json won't work from PHP or from mongo console.

Incorrect JSON

{
    "$and": [{
        "last_update": {
            "$gte": {
                "date": "2016-04-11 03:00:00",
                "timezone_type": 1,
                "timezone": "+00:00"
            },
            "$lt": {
                "date": "2016-04-12 02:59:59",
                "timezone_type": 1,
                "timezone": "+00:00"
            }
        }
    }]
}

Correct JSON

{
    "$and": [{
        "last_update": {
            "$gte": "2016-04-11 03:00:00",
            "$lt": "2016-04-12 02:59:59"
        }
    }]
}

PHP code to generate an incorrect json

$filter = ["\$and" => [array(
                "last_update" => array(
                    "\$gte" => (new MongoDB\BSON\UTCDateTime($currentDay->getTimestamp() * 1000))->toDateTime(),
                    "\$lt" => (new MongoDB\BSON\UTCDateTime($endOfDay->getTimestamp() * 1000))->toDateTime()
                )
        )]];

from mongo-php-driver.

jmikola avatar jmikola commented on August 14, 2024

@renannprado: query criteria should not be using JSON or Extended JSON values. In your last example above, you're converting MongoDB\BSON\UTCDateTime to a DateTime object, which is also incorrect. You should be using the actual BSON type classes provided by the driver (e.g. MongoDB\BSON\UTCDateTime).

This applies to any query criteria, be it the first argument to MongoDB\Driver\Query::__construct(), the mapReduce command's query option, or the $match pipeline operator for an aggregation command.

I don't believe your "Correct JSON" example is actually correct:

{
    "$and": [{
        "last_update": {
            "$gte": "2016-04-11 03:00:00",
            "$lt": "2016-04-12 02:59:59"
        }
    }]
}

That criteria is comparing "last_update" with strings, which only makes sense if "last_update" is a string type. If it is a BSON date, then you'll want to use MongoDB\BSON\UTCDateTime when querying in PHP, or ISODate in the JavaScript shell.

from mongo-php-driver.

MichaelBrenden avatar MichaelBrenden commented on August 14, 2024

How do the two Mongo drivers determine if they can translate something into the ISODate format?

Does mongo.so require a class type of MongoDate, or does it determine by data returned by __toString() (i.e., "0.12345678 1234567890")?

Does mongodb.so require a class type of \MongoDB\BSON\UTCDateTime, or does it determine by data returned by __toString() (i.e., "1234567890123")?

from mongo-php-driver.

jmikola avatar jmikola commented on August 14, 2024

the ISODate format?

For the record, ISODate is just a helper function in the mongo shell. The actual BSON type is 0x09 in the BSON spec and is best referred to as "UTC date time".

Does mongodb.so require a class type of \MongoDB\BSON\UTCDateTime, or does it determine by data returned by __toString() (i.e., "1234567890123")?

The driver requires a MongoDB\BSON\UTCDateTime object in order to encode a BSON date type. The relevant instanceof check during BSON encoding is here if you care to see it. The __toString() function exists purely as a convenience for userland applications. The driver does not use it outside of tests.

The legacy mongo.so driver is similar in that it requires a MongoDate object in order to encode a BSON date type (relevant code is here).

from mongo-php-driver.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.