0
votes

I get an error when trying to aggregate a collection in PHP. Collection "lbls2" contains documents that look like:

{
    "_id" : ObjectID(1234),
    "values" : ["String 1", "String 2", "String 3"]
}

{
    "_id" : ObjectID(5678),
    "values" : ["String 1", "String 4", "String 7"]
}

{
    "_id" : ObjectID(9101),
    "values" : ["String 3", "String 5", "String 10"]
}

When I run db.lbls2.aggregate({'$project' : {'values' : 1, '_id' : 0}}) in the Mongo shell, it returns:

{
    "values" : [
        "String 1",
        "String 2",
        "String 3"
    ]
}
{
    "values" : [
        "String 1",
        "String 4",
        "String 7"
    ]
}
{
    "values" : [
        "String 3",
        "String 5",
        "String 10"
    ]
}

When I run $r = $c_l->aggregate(['$project' => ['values' => 1, '_id' => 0]]); in PHP, it returns:

Fatal error: Uncaught exception 'MongoDB\Exception\InvalidArgumentException' with message '$pipeline is not a list (unexpected index: "$project")' in C:\xampp\htdocs\gc4\vendor\mongodb\mongodb\src\Operation\Aggregate.php:93 Stack trace: #0 C:\xampp\htdocs\gc4\vendor\mongodb\mongodb\src\Collection.php(186): MongoDB\Operation\Aggregate->__construct('gc_dev', 'lbls2', Array, Array) #1 C:\xampp\htdocs\gc4\admin_dashboard.php(9): MongoDB\Collection->aggregate(Array) #2 {main} thrown in C:\xampp\htdocs\gc4\vendor\mongodb\mongodb\src\Operation\Aggregate.php on line 93

Interestingly, db.lbls2.aggregate({'$project' : {'values' : '$values.0', '_id' : 0}}) (projecting values index 0) returns '{ "labels" : [ ] }', so it's possible I may have screwed up the insertion or done something weird. What am I doing wrong?

Here's my PHP script: require ('./vendor/autoload.php');

$client = new MongoDB\Client("mongodb://localhost:27017");
$db = $client->gc_dev;
$c_l = $db->lbls2;

$r = $c_l->aggregate(['$project' => ['values' => 1, '_id' => 0]]);

And here's part of the python script I used to insert the values:

a = urllib2.urlopen('http://urlredacted.com')

a = bs(a)

length = len(a.findAll('a',id=re.compile('rptResults_*')))

for row in a.findAll('a',id=re.compile('rptResults_*')):
    cells = row.get_text()
    labels.append(cells)


lastIndex =len(labels)
for i in range (0,lastIndex):
    labels[i] = unicodedata.normalize('NFKD',labels[i]).encode('ascii','ignore')


#connect to db and insert data
client = MongoClient("mongodb://localhost:27017")
db = client.gc_dev
c_lbls = db.lbls2

lbls_insert = {

        "values" : labels

    }

c_lbls.insert_one(lbls_insert)
1

1 Answers

3
votes

The parameters you are using to the aggregate aren't correct, from the code of mongodb library:

  • @param array $pipeline List of pipeline operations

So it's expecting a list of pipeline operations, you are passing a associative array and the exception is shown. The code generating the exception is here: https://github.com/mongodb/mongo-php-library/blob/master/src/Operation/Aggregate.php#L93

The solution is to pass a numered array as a list of pipeline commands.

$r = $c_l->aggregate([['$project' => ['values' => 1, '_id' => 0]]]);