views:

42

answers:

2

I seem to be having some trouble using the cursor as I try to pull data out of a MongoDB. Here is a screenshot of my simple data structure:

data structure screenshot

I'm trying to use the following:

$collection_name = "users";
$collection = $this->mongo->db->$collection_name;
$which_document = array("email" => $email_address);
$which_fields = array("words");
$cursor = $collection->find($which_document, $which_fields);

But my $cursor does not seem to be going any further into the document than the actual document. In the end, I'm looking to sort() and limit() on the created_at field within the "words" field, but I seem to be at an impasse here. And either MongoDB's error passing isn't very helpful, or I've no idea how to use it properly. (I'd assume the latter.)

One idea: I'm not sure the "words" table being generated inside of square brackets is correct, but here is the code I'm using to insert data here:

function create_word($word, $email_address){
    $collection = 'users';

// make sure word isn't null
if($word !== NULL){

// add new data to the 'words' set
    $new_data = array('$addToSet' => array('words' => array(
                                                            'word' => $word,
                                                            'status' => 'open',
                                                            'created_at' => time()
                                                            )));
    $this->mongo->db->$collection->update(array('email' => $email_address), $new_data);         
}

Thanks so much for any help you can give!

+1  A: 

You can't sort subdocuments. You need to do it on the client side. In your case retrieve the words array:

$array = iterator_to_array($cursor); 
$words = $array[0]["words"];

and then use php to sort the values.

halfdan
Ah, dot notation! Is there a hard-and-fast rule on when one should use dot notation in the php driver? Unfortunately, no luck. Here is a [screenshot](http://droplr.com/hHjj) of a var_dump of the cursor value using [this code](http://droplr.com/QUJW). Did I miss something from your updates? I'm actually going to be sorting on created_at, but I tried to alternate between "1" and "-1", with no differences.
Joshua Cody
I was curious and tried it myself now. Sorting subdocuments doesn't work. The example in the documentation covers a different kind of sorting where you have nested values inside a document and sort all the documents after them and not an nested array.
halfdan
Interesting. This is my first project with MongoDB, from your vantage point, would you suggest some sort of data restructuring? This seems like a fairly important issue, as I'll be essentially paginating this data, it would be very nice to use .limit(), .skip(), and .sort().
Joshua Cody
+1  A: 

Try

$collection->find(array($which_document, $which_fields))->sort(array("words.created_at" => -1));
luckytaxi
Unfortunately I have no luck here. Whether I use 1 or -1, my var_dump remains the same.
Joshua Cody
luckytaxi
Sounds like you and halfdan are both pointing to the same issue. Reading through the thread now, but I'll pose the same question here as I have with him. Would you suggest a data restructuring since I'll be working so intensively with this data?
Joshua Cody
If the "words" array will get large, I would separate it into its own collection.
luckytaxi
Thanks so much, the intangibles of best data structure practices and minor things that won't work are difficult to grasp at first. Looks like I need to break myself of the idea that as much as possible should be stored in a single collection.
Joshua Cody