0

I am trying to do the equivalent of MongoDB, which should return all users called Joe Bloggs, that have at least one address where the City is defined as London:

db.users.findOne() {
    name : "Joe Bloggs",
    addresses : [{city: "London"}]
}

Using the Kohana 3 PHP module Mango: https://github.com/Wouterrr/MangoDB

I can return results based on top level objects like so:

foreach(Mango::factory('users', array(
    'name' => 'Joe Bloggs',
))->load(FALSE) as $user) {
}

But I can't work out how to return results based on objects in arrays, I have tried variations of:

foreach(Mango::factory('users', array(
    'name' => 'Joe Bloggs',
    'addresses' => array('city' => 'London'),
))->load(FALSE) as $user) {
}

and:

foreach(Mango::factory('users', array(
    'name' => 'Joe Bloggs',
    'addresses.$.city' => 'London',
))->load(FALSE) as $user) {
}

I think I'm really close I'm just stuck at the last.

Braiam
  • 1
  • 11
  • 47
  • 78

1 Answers1

1

I'm not familiar with the library you are using, but from a shell you would simply do this:

db.users.find({"name" : "Joe Bloggs", "addresses.city" : "London"});

So most likely, what you are looking for is:

foreach(Mango::factory('users', array(
    'name' => 'Joe Bloggs',
    'addresses.city' => 'London',
))->load(FALSE) as $user) {
}
svjson
  • 2,085
  • 19
  • 13
  • Wouldn't it be `addresses : [{city: "London"}]` from the shell if the structure was `user { "name": "Joe Bloggs", "addresses": { "0": { "address": "1 Oxford Street", "city": "London", "state": "London", "postalcode": "W1D", "country": "UK" } } }` –  Mar 08 '11 at 10:48
  • With [{city: "London"}] you would be matching the entire contents of the array, ie you wouldn't get a match since you have other fields in the embedded object. In the structure you posted in the comment, things are different because you are not actually using arrays, but embedded objects. – svjson Mar 08 '11 at 11:33
  • To clarify - in the structure you posted, the '..."addresses": { "0": { ...' doesn't indicate an array. The "0" is simply a string key just like any other, and you could match using { "addresses.0.city" : "London" }. But this is most likely not what you want, I'm pretty sure you want a real, proper, array. – svjson Mar 08 '11 at 11:38
  • Sorry that should have read: `user { "name": "Joe Bloggs", "addresses": [ { "address": "1 Oxford Street", "city": "London", "state": "London", "postalcode": "W1D", "country": "UK" } ] }` RockMongo displays it with a numeric key for some reason - but it is actually an array. - `'addresses.city' => 'London'` is still returning all results regardless of city! –  Mar 08 '11 at 12:15
  • That is very odd - it works perfectly for me. Are you seeing the same behavior when you execute the query from the shell? In my shell, the command `db.users.find({"addresses.city" : "London"})` returns documents for London only. If the same query through Mango doesn't work, I'm afraid I'm out of ideas. – svjson Mar 08 '11 at 13:29
  • You're right! This does work perfectly in the shell - it was just the way of doing it with the ohana library is different - but in theory definately `addresses.city => 'London'` is correct. –  Mar 08 '11 at 14:51