I need to dynamically build a complex MongoDB query before executing it in PHP. My query line looks like $cursor = $c_sbc->aggregate($query_string);, where $query_string is something like [['$match' => ['symbol' => $sym]],['$project' => ['first' => ['$arrayElemAt' => ['$data.1000', -1]]]]].
Copy-and-pasting the above-given example to replace $query_string gives the desired result. However, running it with $query_string in place gives an error saying it expects an array, not a string. How do I get this query to work?
Catchable fatal error: Argument 1 passed to MongoDB\Collection::aggregate() must be of the type array, string given, called in C:\xampp\htdocs\gc5\screen.php on line 60 and defined in C:\xampp\htdocs\gc5\vendor\mongodb\mongodb\src\Collection.php on line 163
Edit: relevant PHP
$query = $_POST['screen'];
$t = array(
"revenue" => 1000,
"costofgoodssold" => 1001
);
$data_array = [];
//turn words into data.XXXX codes
function translate($match){
global $t;
global $data_array;
foreach($match as $m){
$d = "data.".$t[$m];
$data_array[] = $d;
return $d;
}
}
$query = preg_replace('/\s/', '', $query); //strip whitespace
$query = strtolower($query);
$query = preg_replace_callback('/([A-Z]+)/i','translate', $query);
echo "<br>Query: ";
print_r($query);
echo "<br>";
$client = new MongoDB\Client("mongodb://localhost:27017");
$db = $client->gc_dev;
$c_sbc = $db->screenByCompany;
$for_years = [-1]; //default is TTM
$symbols = ['goog', 'fb', 'crmt', 'vlgea', 'ko', 'pep', 'flws'];
for($i=0;$i<count($symbols);$i++){
$sym = $symbols[$i];
for($j=0;$j<count($for_years);$j++){
$k = $for_years[$j];
//build query for data
$data_query = "";
foreach($data_array as $d){
if($data_query == ""){ //first go-around, no need for comma
$data_query .= "['first' => ['\$arrayElemAt' => ['$".$d."', ".$k."]]]";
}else{
//$data_query .= ",['second' => ['\$arrayElemAt' => ['$".$d."', ".$k."]]]";
}
$query_string = "[['\$match' => ['symbol' => \$sym]],['\$project' => ".$data_query."]]";
}
echo "<br>\$query_string: ".$query_string;
$cursor = $c_sbc->aggregate($query_string);
//$cursor = $c_sbc->aggregate([['$match' => ['symbol' => $sym]],['$project' => ['first' => ['$arrayElemAt' => ['$data.1000',-1]]]]]);
$cursor = iterator_to_array($cursor);
//var_dump($cursor);
echo "Cursor: ".$cursor[0]['first'] . "<br><br>";
}
Results in:
Query: (data.1000-data.1001)>1,000
$query_string: [['$match' => ['symbol' => $sym]],['$project' => ['first' => ['$arrayElemAt' => ['$data.1000', -1]]]]]
Catchable fatal error: Argument 1 passed to MongoDB\Collection::aggregate() must be of the type array, string given, called in C:\xampp\htdocs\gc5\screen.php on line 60 and defined in C:\xampp\htdocs\gc5\vendor\mongodb\mongodb\src\Collection.php on line 163