I have a two collections one of all the people I am following and another of what they have been posting on social networking sites like Twitter and Facebook.
The following collection has a subarray of the _id of the feed collection of each user which each status has the word owner and that has the ObjectId that the owner which is the same as the following key. Here is an example.
'_id' => new MongoId("REMOVED"),
'following' =>
array (
'0' => 'ObjectId("53bf464ee7fda8780c8b4568")',
'1' => 'ObjectId("53b00ab5e7fda8304b8b4567")',
),
'owner' => new MongoId("53b9ea3ae7fda8863c8b4123"),
and in the feed you will see that the following.0 status below
array (
'_id' => new MongoId("REMOVED"),
'owner' => new MongoId("53bf464ee7fda8780c8b4568"),
'status' => ' love this video - Pedigree Shelter dogs http://youtube.com/watch?v=5v5Ui8HUuN8',
'timestamp' => new MongoDate(1405044327, 565000),
)
While I can loop through one by one, I can't for some reason do an $or search. I am not quite understanding how I loop through the following array and add it to the search query before I ran the query.
collection = static::db()->feed;
$where=array( '$or' => array(array('owner' => new MongoId($following.0)))));
$feed = $collection->find($where);
return $feed;
now I understand I will somehow have to loop the $where=array( '$or' => array(array('owner' => new MongoId($following.0))))); But I am just not 100% sure how to do this.
Update
As per the answer below I had to edit the array that was returned - now I have only got this working manually and can't seem to get the PHP script to do it.
Answer Returns
Array ( [owner] => Array ( [$in] => Array ( [0] => new MongoId("53bf464ee7fda8780c8b4568") [1] => new MongoId("53b00ab5e7fda8304b8b4567") ) ) )
Correct:
Array ( "owner" => Array ( '$in' => Array ( "0" => new MongoId("53bf464ee7fda8780c8b4568"), "1" => new MongoId("53b00ab5e7fda8304b8b4567") ) ) )
I am not sure how else to get this to work.
current PHP
$collection = static::db()->following;
$following = $collection->findOne(array ('owner' => new MongoId($_SESSION['user_information'][0]['_id'])));
$follow = $following['following'];
$collection = static::db()->feed;
$where=array("owner" => array( '$in' =>$follow));
print_r($where);
$feed = $collection->find($where);
print_r($feed);
return $feed;
I have fixed a small issue with the collection and now the return array shows
Array ( [owner] => Array ( [$in] => Array ( [0] => MongoId Object ( [$id] => 53bf464ee7fda8780c8b4568 ) [1] => MongoId Object ( [$id] => 53b00ab5e7fda8304b8b4567 ) ) ) )
However, I still can't get it to return the feed like this one:
array (
'_id' => new MongoId("53bf4667e7fda8700e8b4567"),
'owner' => new MongoId("53bf464ee7fda8780c8b4568"),
'status' => ' love this video - Pedigree Shelter dogs http://youtube.com/watch?v=5v5Ui8HUuN8',
'timestamp' => new MongoDate(1405044327, 565000),
)
I am presuming here that this is just a PHPism in the way things are displayed and that your following array is an actual array and not a hash/map, which would generally look like this in a JSON representation:
{
"following": [
ObjectId("53bf464ee7fda8780c8b4568"),
ObjectId("53b00ab5e7fda8304b8b4567"),
],
"owner": ObjectId("53b9ea3ae7fda8863c8b4123"),
}
In which case the "following" is already an actual array, and if you just want to .find() all the "feed" items for the people you are following, then you just pass that to the $in operator for your query selection:
$where = array( "owner" => array( '$in' => $following ) );
$feed = $collection->find($where);
return $feed;
The returned cursor will only contain results from the feed where the "owner" is present in your "following" array from the other collection item.
Watch this code:
$list = array(new MongoId(), new MongoId, new MongoId());
$doc = array( "owner" => array( '$in' => $list ));
echo json_encode( $doc, JSON_PRETTY_PRINT );
Despite how this serializes for JSON by this method the equivalent JSON is:
{
"owner": {
"$in": [
ObjectId("53bf8157c8b5e635068b4567"),
ObjectId("53bf8157c8b5e635068b4568"),
ObjectId("53bf8157c8b5e635068b4569")
]
}
}
That is how the BSON will serialize and is the correct query.
(Answer added on behalf the question author to move it to the answer space).
The issue was fixed when I used the following:
var_dump(iterator_to_array($feed));
Related
I have a large multidimensional array that looks like the below.
I want to remove duplicate arrays based on the ID, however, I am struggling to achieve this.
I want the duplicates to work over the entire array, so you can see that ID 1229873 is a duplicate, in the array 2021-07-07 and 2021-07-09, it should therefore be removed from 2021-07-09
How would I achieve this? array_unique has not worked for me.
$data = array (
'2021-07-07' =>
array (
0 =>
array (
'id' => 5435435,
'homeID' => 8754,
'match_url' => '/usa/reading-united-ac-vs-ocean-city-noreasters-fc-h2h-stats#1229873',
'competition_id' => 5808,
'matches_completed_minimum' => 12,
),
1 =>
array (
'id' => 1229873,
'homeID' => 8754,
'match_url' => '/usa/reading-united-ac-vs-ocean-city-noreasters-fc-h2h-stats#1229873',
'competition_id' => 5808,
'matches_completed_minimum' => 12,
),
),
'2021-07-09' =>
array (
0 =>
array (
'id' => 3243234,
'homeID' => 8754,
'match_url' => '/usa/reading-united-ac-vs-ocean-city-noreasters-fc-h2h-stats#1229873',
'competition_id' => 5808,
'matches_completed_minimum' => 12,
),
1 =>
array (
'id' => 1229873,
'homeID' => 8754,
'match_url' => '/usa/reading-united-ac-vs-ocean-city-noreasters-fc-h2h-stats#1229873',
'competition_id' => 5808,
'matches_completed_minimum' => 12,
),
),
);
This is a perfect case for array_uunique()! No wait, scratch that. The PHP devs refused to implement it for the perfectly valid reason of... [shuffles notes] "the function name looks like a typo".
[sets notes on fire]
Anyhow, you just need to iterate over that data, keep track of the IDs you've seen, and remove entries that you've already seen.
$seen = [];
foreach(array_keys($data) as $i) {
foreach(array_keys($data[$i]) as $j) {
$id = $data[$i][$j]['id'];
if( in_array($id, $seen) ) {
unset($data[$i][$j]);
} else {
$seen[] = $id;
}
}
}
I've opted for the foreach(array_keys(...) as $x) approach as avoiding PHP references is always the sane choice.
Run it.
I am Sure That is the way which you want to get the unique array.
$unique = array_map("unserialize", array_unique(array_map("serialize", $data)));
echo "<pre>";
print_r($unique);
echo "</pre>";
I am building an array (json encoded) and returning it to the caller. My output currently looks like this:
[{"org_id":1,"org_name":"Org 1"},{"org_id":4,"org_name":"Org 4"}]
I want to add a name so that output looks like this:
{
“orgs” : [
{"org_id":1,"org_name":"Org 1"},
{"org_id":4,"org_name":"Org 4"}
]
}
Here is my current code:
// if orgs were found then
if ( is_array($orgs) && !empty($orgs) ) {
$json_orgs = json_encode($user_orgs);
// else return an empty array
} else {
$user_orgs = array();
}
I am fairly new to OO coding, so I have not figured out how to initialize an object so that "orgs" is present. Maybe I don't even need an object. Any help would be greatly appreciated.
Before you json encode the array, just wrap it in another one:
$newArray = ['orgs' => $yourCurrentArray];
Then you json encode the new variable instead.
If you rather not create a new array, you can simply do:
json_encode(['orgs' => $yourCurrentArray]);
This doesn't really have anything to do with OOP since you're just working with arrays. Associative arrays becomes objects when encoded into JSON.
You didn't say exactly how you're generating the JSON at the moment, or from what object/variable in PHP, or with what structure (there is more than one possible way).
But in general, here's how you could do it with an associative array:
$data = array (
'orgs' =>
array (
0 =>
array (
'org_id' => 1,
'org_name' => 'Org 1',
),
1 =>
array (
'org_id' => 4,
'org_name' => 'Org 4',
),
),
)
And then json_encode that to get the JSON.
(Hint: you can simply do the process in reverse to generate this example code from the desired JSON.)
You can achieve this by adding a key, for example:
// variable holding your data
$data;
// return statement in your controller
return ['orgs' => $data];
You just need to decode this with json_decode() and then you get like this
array (
0 =>
array (
'org_id' => 1,
'org_name' => 'Org 1',
),
1 =>
array (
'org_id' => 4,
'org_name' => 'Org 4',
),
)
then you need to add parant array on it
array( "orgs"=> array (
0 =>
array (
'org_id' => 1,
'org_name' => 'Org 1',
),
1 =>
array (
'org_id' => 4,
'org_name' => 'Org 4',
),
)
)
then again encode it and you will get your answer
I am doing Jira REST API calls and I am wondering how I can dynamically add more than one component to the components field using REST API in PHP. I have the following code, works when I set it static, but not sure how to do it dynamically.
Example of static component set:
$data = array(
'fields' => array(
'project' => array(
'key' => $rowAnswers["Key"]
),
'summary' => $rowAnswers["Summary"],
'description' => $rowAnswers["Description"],
'issuetype' => array(
'name' => $rowAnswers["IssueType"]
),
'components' => array(
array(
"name" => "component1"
),
array(
"name" => "component2"
)
)
),
);
My array that I want to replace the static content with:
$components = explode(",", $rowAnswers["Components"]);
$arr = array();
foreach($components as $value){
$array = array("name"=>$value);
array_push($arr,$array);
}
Replacing
'components' => array(
array(
"name" => "component1"
),
array(
"name" => "component2"
)
)
with
'components' => [
$arr
]
doesn't work, I get:
"{"error":false,"error_msg":"","data":"{\"errorMessages\":[],\"errors\":{\"components\":\"expected Object\"}}"}"
I see on an api call to get a request it looks like this:
[components] => Array
(
[0] => stdClass Object
(
[name] => component1
)
[1] => stdClass Object
(
[name] => component2
)
)
But I am unsure how to transform an array into this type of object or request in PHP. Calling with PHP-cURL and json_encoding the data it sends.
Thanks in advance!
you need to decode your json as associative array by setting the second parameter to true
check out the json_decode
assoc
When TRUE, returned objects will be converted into associative arrays.
To fix this I had to do the following:
When creating the array from the DB:
$components = explode(",", $rowAnswers["Components"]);
$arr = array();
foreach($components as $value){
$array = json_decode(json_encode(array("name"=>$value)), FALSE);
array_push($arr,$array);
}
Then to set the component in the request:
'components' => $arr
Thanks
I am trying to create an array when im using TMDB(The movie database) API, I am using this wrapper for PHP.
I am trying to do this
require_once('../classes/tmdb-api.php');
// if you have no $conf it uses the default config
$tmdb = new TMDB();
//Insert your API Key of TMDB
//Necessary if you use default conf
$tmdb->setAPIKey('myKEy');
//Title to search for
$title = $_POST['searchTerm'];
$movies = $tmdb->searchMovie($title);
// returns an array of Movie Object
$movieArray = array();
$movieSearchArray = array();
foreach($movies as $movie) {
$movieTitle = $movie->getTitle();
$movieSearchArray[$movieTitle] = ['ID'][$movie->getID()];
$movieSearchArray[$movieTitle] = ['Trailer'][$movie->getTrailer()];
}
$movieArray[] = $movieSearchArray;
print_r($movieArray);
So for example when a user searches 'Rocky' It will bring back multiple different movie titles but for each of the movie titles I want to create an array like this for example, I am trying to do this in the foreach loop but what am i doing wrong?
[Rocky] => (
"id" = "2",
"rating" = "4"
)
Keep in mind that there could be 10s of different movies. This is what i get returned when I search 'Rocky' right now.
Array
(
[0] => Array
(
[Rocky] =>
[Rocky II] =>
[Rocky IV] =>
[Rocky V] =>
[Rocky Balboa] =>
[Rocky III] =>
[Rocky VI] =>
[Creed] =>
[The Real Rocky] =>
[Rocky Marciano] =>
[Where is Rocky II?] =>
[Rocky Handsome] =>
[Rocky Road] =>
[Rocky Mountain] =>
[Rocky Pink] =>
[Rocky and Bullwinkle] =>
[The Rocky Horror Picture Show] =>
[Rocky Mountain Grandeur] =>
)
)
I guess you can do that, with only exception of assigning item to an array, indices in [] must be before equal (=) sign, or you have to assign whole array with keys and values.
so either
foreach($movies as $movie) {
$movieTitle = $movie->getTitle();
$movieSearchArray[$movieTitle]['ID'] = $movie->getID();
$movieSearchArray[$movieTitle]['Trailer'] = $movie->getTrailer();
}
or
foreach($movies as $movie) {
$movieSearchArray[$movie->getTitle()] = array(
'ID' => $movie->getID(),
'Trailer' => $movie->getTrailer()
);
}
and so on for other data in the $movie object
is it possible to get the new/updated _id after the query?
example code:
$key = array( 'something' => 'unique' );
$data = array( '$inc' => array( 'someint' => 1 ) );
$mongodb->db->collection->update( $key, $data, array( 'upsert' => true ) );
$key is not holding the new/old _id object and i assume that $data will not either because its just an instruction.
Yes -- It is possible using a single query.
MongoDB includes a findAndModify command that can atomically modify a document and return it (by default it actually returns the document before it's been modified).
The PHP drivers don't include a convenient method for this on the collection class (yet -- check out this bug), but it can still be used (note that my PHP is terrible, so I may very well have made a syntax error in the following snippet):
$key = array( 'something' => 'unique' );
$data = array( '$inc' => array( 'someint' => 1 ) );
$result = $mongodb->db->command( array(
'findAndModify' => 'collection',
'query' => $key,
'update' => $data,
'new' => true, # To get back the document after the upsert
'upsert' => true,
'fields' => array( '_id' => 1 ) # Only return _id field
) );
$id = $result['value']['_id'];
Just in case someone stumbles across this question like I did, Mongo will actually modify the input array when you call MongoCollection->save(); - appending the id to the end.
So, if you call:
$test = array('test'=>'testing');
mongocollection->save($test);
echo $test['_id'];
You will have the mongo id for that object.
I ran into this issue and worked around it by querying back the _id after the upsert. I thought I'd add some of my findings in case they're useful to anyone who comes here searching for info.
When the upsert results in a new document being created in the collection, the returned object contains the _id (here's a print_r of an example):
Array
(
[updatedExisting] => 0
[upserted] => MongoId Object
(
[$id] => 506dc50614c11c6ebdbc39bc
)
[n] => 1
[connectionId] => 275
[fsyncFiles] => 7
[err] =>
[ok] => 1
)
You can get the _id from this:
$id = (string)$obj['upserted'];
However, if the upsert resulted in an existing document being updated then the returned object does not contain _id.
Give this a shot :
function save($data, $id = null) {
$mongo_id = new MongoId($id);
$criteria = array('_id' => $mongo_id);
// Wrap a '$set' around the passed data array for convenience
$update = array('$set' => $data);
$collection->update($criteria, $update, array('upsert' => true));
}
So lets say the passed $id is null, a fresh MongoId is created, otherwise it just converts the existing $id to a MongoId object.
Hope this helps :D
The update method returns an array with the ID of the document UPSERTED:
Array
(
[ok] => 1
[nModified] => 0
[n] => 1
[err] =>
[errmsg] =>
[upserted] => MongoId Object
(
[$id] => 5511da18c8318aa1701881dd
)
[updatedExisting] =>
)
You can also set fsync to true in an update/upsert, to get the _id returned to the object that has been passed to the update.
$save = array ('test' => 'work');
$m->$collection->update(criteria, $save, array('fsync' => true, 'upsert' => true));
echo $save['_id']; //should have your _id of the obj just updated.