3

I am retrieving a DocumentSet in Lithium from MongoDB, but I don't want to process the documents all at once. Instead I would like to have a filter, which I just could tell something like this:

$manyDocuments->giveMeTheOneWhere(array('foo' => 'bar'));

I already tried to do it this way, but it didn't work:

$manyDocuments->find(function($singleDocument){
    return ($singleDocument->foo == 'bar');
});

Even if I manually return true inside the closure, it always returns an empty DocumentSet.

Just to add clarity: I am not looking for a database-operation, instead I want to get one out of an already existent DocumentSet. Is there a fancy way to achieve this or do I need to iterate through the set using a custom function?

YMMD
  • 3,730
  • 2
  • 32
  • 43

3 Answers3

2

That looks right to me. Is that the exact code you are using?
For example, is the 'bar' value you are using something you are passing in?

ton.yeung
  • 4,793
  • 6
  • 41
  • 72
  • You probably were reminding me that variables are not visible inside the closure unless you don't explicitly announce them using `function($singleDocument) use ($variableToCompare){` Yes, for my test I did use a fix string. – YMMD Apr 03 '12 at 10:09
  • @YMMD Yea, I was having that problem for when I tried using the find method. How are you troubleshooting the issue? Have you tried putting a break point inside the closure and inspecting your foo field? I've had issues before where my data had typos and the strings don't completely match. – ton.yeung Apr 03 '12 at 16:38
1

I'm on the latest of the master branch of Lithium and wrote this unit test which works for me. I'm not really sure why you're getting an empty DocumentSet.

$docs = new DocumentSet(array('data' => array(
    new Document(array('data' => array(
        'id' => 1,
        'foo' => 'bar'
    ))),
    new Document(array('data' => array(
        'id' => 2,
        'foo' => 'baz'
    ))),
    new Document(array('data' => array(
        'id' => 3,
        'foo' => 'bar'
    ))),
    new Document(array('data' => array(
        'id' => 4,
        'blah' => 'ack'
    )))
)));
$filtered = $docs->find(function($doc) {
    return $doc->foo === 'bar';
});
$expected = array(
    '0' => array('id' => 1, 'foo' => 'bar'),
    '2' => array('id' => 3, 'foo' => 'bar')
);
$this->assertIdentical($expected, $filtered->data());
rmarscher
  • 5,596
  • 2
  • 28
  • 30
0

Instead of using find() I just used first() with a closure. This works as expected. Sadly that was the only thing I didn't try before. Excuse me for answering my own question.

Anyway I'd still be interested in a way to get another Document Set.

YMMD
  • 3,730
  • 2
  • 32
  • 43