coen-hyde / Shanty-Mongo

Shanty Mongo is a mongodb library for the Zend Framework. Its intention is to make working with mongodb documents as natural and as simple as possible. In particular allowing embedded documents to also have custom document classes.
Other
200 stars 52 forks source link

getProperties on Shanty_Mongo_Document #66

Closed ZtF closed 12 years ago

ZtF commented 12 years ago

Perhaps it would be nice to include something like this to Shanty_Mongo_Document. Haven't tested it much and it's just quick and dirty solution but it's good enough for me though.

/*
 * Get array of properties (recursive)
 * @param Shanty_Mongo_Document $document
 * @return array
 */
public function getProperties($document = null){
    if(is_null($document))
        $document = $this;
    $keys = $document->getPropertyKeys();
    foreach($keys as $key){
        if($document->$key instanceof Shanty_Mongo_Document){
            $rval[$key] = $document->getProperties($document->$key);
        } else {
            $rval[$key] = $document->$key;
        }
    }
    return $rval;
}
ghost commented 12 years ago

If I'm reading this right, it's the same thing I have called as import():

function import($data) { foreach( $data as $k => $v) { $this->setProperty($k, $v); } }

Which I have defined in my AppModel extending Shanty_Mongo_Document.

ZtF commented 12 years ago

Not really. This is something like export. Imagine a situation when I wish to export data eg. in JSON. And that's exactly I'm trying to do.

tonymillion commented 12 years ago

On that subject it would be really nice to define a set of 'external' properties that will show on export() or something so there is a clean way to export data from a object without having to unset() all the fields you don't want to pass to a client.

ZtF commented 12 years ago

Well that depends... I'd say it would be cleaner to have only a possibility to include internal props (such as _id or _type) or not. Any other properties IMO should be (and are) defined as a second param in find(), all() etc. methods.

gwagner commented 12 years ago

I my branch i have a fix for the exclude (because you can not include and exclude fields at the same time). Currently the exclude operation is trying to include _id and _type, but we dont need to include those fields if we are only excluding a few other fields.

tholder commented 12 years ago

I've found overriding export in my own models the cleanest way to go.

ZtF commented 12 years ago

Agreed

gwagner commented 12 years ago

While i agree that it may be clean in code to over ride export, you are still increasing the overhead in your application by bringing in an entire record and then scaling it back with export later. If you dont need the data, exclude it form your query in the first place and dont transmit it from the mongo server. By grabbing the entire record, your grabbing extra bits that need to transmit over the wire needlessly. By excluding fields in the query you are saving milliseconds all over your application rather than trimming back an export once the time over the wire has already been wasted.

tonymillion commented 12 years ago

Ok for example in a set I use all the records have created/modified/wholastmodified(and more), while I need those fields in the server side code, the client never has any need to see them. So while I sometimes have to pull them back, I don't really want that information going to the client.

Its not exactly a huge deal to work around, but it would be nice if there was a 'export like' function that only exported data from a list of 'allowed' fields to subsequently encode to JSON or whatever.

tholder commented 12 years ago

I think this is possibly two issues being discussed here. You'd obviously only select what you required from Mongo to keep what's going over the wire as small as possible. But, in terms of making sure you never export something you want to hide, overriding export seems like the best way to go.

gwagner commented 12 years ago

You are supposed to do that in your query to mongo:

$mongoObject->all(
    array(
        /* QUERY PARAMERTERS */
    ),
    array(
        'field_to_exclude' => -1,
        'field_to_exclude_2' => -1, 
    )
);

That way in your client side code, you can exclude the fields you want, and in the server side code you can exclude the fields you want. The only problem is, in this fork of the code, you cant exclude fields because Coen has things setup to always include _id and _type, i have modified the Document.php file to allow a user to exclude fields.

gwagner commented 12 years ago

I have just committed a change to my branch that will let you do the query above, and then let you properly export (skipping the requirement check)

This makes export() work and query limiting work for keeping OtW transmission minimal.