i'm trying to update an inner array within a mongo document:
$find = array('_id' => new mongoId($qId));
$push = array('$push' => array('questions', ['q' => $question, 'a' => $answers] ) );
$this->db->questionaires->update( $find, $push );
But I keep getting this error:
Invalid modifier specified: $push
My collection is structured like this:
> db.questionaires.findOne();
{
"_id" : ObjectId("57e7c1fea7312a9958601a85"),
"title" : "ff",
"respondantgroup" : "579dca85a7b294c3f030fb8d",
"responsible" : "579dc862a7b294c3f030fb8c",
"questions" : [
{
"q" : "",
"a" : [ ]
}
]
}
Any suggestions?
Related
I'm trying to build an aggregation query in Parse's PHP SDK, and I'm stuck in the "lookup" area, I saw a JS example regarding this but it doesn't work in my case.
I have a table of users, which contains a "Tags" field of type Array, the array is actually an array of pointers, that point to a separate Tag class.
What I'm trying to achieve is to list most popular Tags based on their usage, so basically I need to query the users class and group the Tags that exist in the array, I already achieved this, but I'm stuck with the lookup part, the query currently returns an array of Tags pointers, what I want is to pull the object of those pointers.
Here's what I have currently:
$query = new ParseQuery('_User');
$pipeline = [
'project' => ['tags' => 1],
'unwind' => '$tags',
'group' => [
'objectId' => '$tags.objectId',
'count' => ['$sum' => 1]
],
'sort' => [ 'count' => -1],
'limit' => 10,
];
try {
return $query->aggregate($pipeline);
} catch (ParseException $ex) {
return $ex->getMessage();
}
And here's a snippet of what the _User collection looks like:
{
"_id" : "5BuBVo2GD0",
"email" : "test#test.com",
"username" : "test#test.com",
"lastname" : "Doe",
"firstname" : "John",
"_created_at" : ISODate("2017-01-23T09:20:11.483+0000"),
"_updated_at" : ISODate("2019-02-15T02:48:30.684+0000"),
"tags" : [
{
"__type" : "Pointer",
"className" : "Tag",
"objectId" : "St2gzaFnTr"
},
{
"__type" : "Pointer",
"className" : "Tag",
"objectId" : "LSVxAy2o74"
}
],
"_p_country" : "Country$4SE8J4HRBi",
}
And the Tag collection looks like this:
{
"_id" : "St2gzaFnTr",
"name" : "Music",
"_created_at" : ISODate("2018-10-22T20:00:10.481+0000"),
"_updated_at" : ISODate("2018-10-22T20:00:10.481+0000")
}
Any help would be appreciated!
Thanks in advance
Not sure if this is a direct answer, but here's a working aggregation on tags sorting for freq...
public function tagHistogram(Request $request, Response $response, array $args): Response {
$pipeline = [
'unwind' => '$tags' ,
'sortByCount' => '$tags',
'limit' => 1000,
];
$query = new ParseQuery('Product');
$result = $query->aggregate($pipeline);
$result = array_map(
function ($e) {
$e['name'] = $e['objectId'];
unset($e['objectId']);
return $e;
},
$result
);
return $response->withJson($result);
}
I am at my first steps with mongoDB and php, trying to figure out how aggregations works. I have an approximate idea on how to use them from the command line but I am trying to translate this for the php driver. I am using the restaurants dexample DB, a list of records like this
{
"_id" : ObjectId("59a5211e107765480896f3f8"),
"address" : {
"building" : "284",
"coord" : [
-73.9829239,
40.6580753
],
"street" : "Prospect Park West",
"zipcode" : "11215"
},
"borough" : "Brooklyn",
"cuisine" : "American",
"grades" : [
{
"date" : ISODate("2014-11-19T00:00:00Z"),
"grade" : "A",
"score" : 11
},
{
"date" : ISODate("2013-11-14T00:00:00Z"),
"grade" : "A",
"score" : 2
},
{
"date" : ISODate("2012-12-05T00:00:00Z"),
"grade" : "A",
"score" : 13
},
{
"date" : ISODate("2012-05-17T00:00:00Z"),
"grade" : "A",
"score" : 11
}
],
"name" : "The Movable Feast",
"restaurant_id" : "40361606"
}
I just want to count how many restaurants for location, what I am doing is
$client = new MongoDB\Client("mongodb://localhost:27017");
$collection = $client->myNewDb->restaurants;
$results = $collection->aggregate(
[
'name' => '$name'
],
[
'$group' => [
'cuisine' => ['sum' => '$sum']
]
]
);
and I am getting this error
Fatal error: Uncaught exception 'MongoDB\Exception\InvalidArgumentException'
with message '$pipeline is not a list (unexpected index: "name")'
any idea? I can't find any good documentation on php.net.
thanks
M
Just take a look into documentation, and you will see, that the pipelines must be passed as an array.
The aggregate method accepts two parameters $pipelines and $options (public function aggregate(array $pipeline, array $options = [])).
Also as was mentioned before, the $group must have the _id element.
Groups documents by some specified expression and outputs to the next
stage a document for each distinct grouping. The output documents
contain an _id field which contains the distinct group by key. The
output documents can also contain computed fields that hold the values
of some accumulator expression grouped by the $groupās _id field.
$group does not order its output documents.
https://docs.mongodb.com/manual/reference/operator/aggregation/group/
So your code must look like this:
$results = $collection->aggregate([
[
'$group' => [
'_id' => '$cuisine',
'sum' => ['$sum' => 1],
'names' => ['$push' => '$name']
]
]
]);
This code groups documents by cuisine element, counts the items and collects all name values into array.
Ok, guys. As most of you might know, there is this new MongoDB Driver for PHP 7 out there. I was trying it out. I got stuck at this query here :
There is a collection like this:
{
"_id" : ObjectId("592d026e2a5e742704e60055"),
"name" : "One",
"conn" : [
{
"_id" : ObjectId("592d03cd3c83d5265c004d0b"),
"name" : "MongoDB Fans",
"comments" : "nice!"
},
{
"_id" : ObjectId("592d06513c83d5265c004d17"),
"name" : "SQL Fans",
"comments" : "not so nice!"
}
]
},
{
"_id" : ObjectId("592d0eec2a5e742704e60056"),
"name" : "Two",
"conn" : [
{
"_id" : ObjectId("592d0ef13c83d5265c004d37"),
"name" : "Cassandra Fans",
"comments" : "spooky!"
}
]
}
Now, what I want to achieve is this:
1. Find all "conn" fields (irrespective of which document they belong to) that contain a user input (say "xyz") in "name" as a sub-string.
2. Project the selected "conn" fields out.
I have tried using the following filters and options without success (Almost all of these return all the "conn" subsets instead of only the filtered subsets):
$filters = ["conn.name" => new MongoDB\BSON\Regex($name,'i')];
$options = ["projection" => ["_id" => 0,"conn" =>1];
$filters = ["conn" => ["\$all" =>["name" => new MongoDB\BSON\Regex($name,'i')]]];
$options = ["projection" => ["_id" => 0,"conn" =>1];
$filters = ["conn.name" => '/'.$name.'/i'];
$options = ["projection" => ["_id" => 0,"conn" =>1];
NOTE: I am using PHP 7 and the latest mongod PECL extension
I am new with mongo.
I try to get a subDocument of a document, here is my document :
{
"_id" : ObjectId("5900ab35c720b210c000032c"),
"name" : "B 1",
"providers" : [
{
"id" : ObjectId("59030550c720b211dc005e9e"),
"name" : "F 1"
},
{
"id" : ObjectId("59030577c720b211dc005e9f"),
"name" : "F 2"
}
]
}
and I want to get this subDocument :
{
"id" : ObjectId("59030577c720b211dc005e9f"),
"name" : "F 2"
}
I think I need to use these class : http://php.net/manual/en/mongocollection.aggregate.php but I didn't manage to use it with my manager instance of the class : http://php.net/manual/en/class.mongodb-driver-manager.php.
The PHP Manual do not show how to use it with the new Driver.
Can someone help me?
Thank you and Good Day !
You don't have to use aggregation for the task.
You can use regular queries for selecting the first matching sub document in the embedded arrays.
You can approach it in a couple of ways.
$Positional Projection
$filter = ['_id' => new MongoDB\BSON\ObjectID("5900ab35c720b210c000032c"), 'providers.id' => new MongoDB\BSON\ObjectID("59030577c720b211dc005e9f") ];
$options = ['projection' => ['_id' => 0, 'providers.$' => 1],];
$elemMatch Projection
$filter = ['_id' => new MongoDB\BSON\ObjectID("5900ab35c720b210c000032c")];
$options = [
'projection' => ['_id' => 0, 'providers' => ['$elemMatch'=> ['id' => new MongoDB\BSON\ObjectID("59030577c720b211dc005e9f")]]],
];
You'll use the executeQuery to run regular queries.
$query = new \MongoDB\Driver\Query($filter, $options);
$cursor = $manager->executeQuery(dbName.collectionName, $query);
I have the following command line mongodb query:
db.getCollection('Data').aggregate([
{'$project' : {"_id":"$_id",
"g":"$g",
"value": {'$substr':["$g",0,4]},
}
}])
The result of this query is:
{
"result" : [
{
"_id" : NumberLong(1),
"g" : "1383,09,1,2000",
"value" : "1383"
},
{
"_id" : NumberLong(2),
"g" : "1499,06,1,1",
"value" : "1499"
},
],
"ok" : 1.0000000000000000,
"$gleStats" : {
"lastOpTime" : Timestamp(0, 0),
"electionId" : ObjectId("564d7df200e15758444e9a7d")
}
}
Now I want to use this query in a php file.
Especially how can I use $substr within $project with aggregate in PHP?
You need to use the MongoCollection::aggregate method
$pipeline = array(
'$project' => array(
'g' => '$g',
'value' => array('$substr' => array('$g', 0,4))
)
);
$results = $collection->aggregate($pipeline)