Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support MongoDB embedded documents #2492

Closed
mohorev opened this issue Feb 19, 2014 · 17 comments
Closed

Support MongoDB embedded documents #2492

mohorev opened this issue Feb 19, 2014 · 17 comments
Labels

Comments

@mohorev
Copy link
Contributor

@mohorev mohorev commented Feb 19, 2014

Extension for MongoDB without the support of embedded documents does not allow to implement all the features of this database. It's sad.

http://docs.mongodb.org/manual/core/data-modeling-introduction/

@mitalcoi
Copy link
Contributor

@mitalcoi mitalcoi commented Feb 19, 2014

if you want to use all mongodb features, you really don't need in Active Record

@Sammaye
Copy link

@Sammaye Sammaye commented Feb 19, 2014

How are they not supported?

What I mean is that subdocuments are just a map within a variable in the class (document) as such I am confused how it's not supported.

@mohorev
Copy link
Contributor Author

@mohorev mohorev commented Feb 19, 2014

I do not speak English so I try to translate through an online translator. So there will be mistakes in the text. Sorry.

My collection, for example:

{
    'name' => 'Books',
    'settings' => [
        'general' => [
            'field1' => 10,
            'field2' => 30,
        ],
        'other' => [
            'field2' => 'value1',
            'field2' => 'value2',
        ]
    ],
    'ramdom' => 1234567
},
{
    ... // 
}

I am trying to describe it in the model

class MyCollection extends ActiveRecord
{
    public function attributes()
    {
        return ['_id', 'name', 'settings', 'random'];
    }
}

How can I make a form for making this record?
how I should be validate model if the settings.general.field1 is integer only?
How can I simply change the nested attribute settings.general.field2?

@Sammaye
Copy link

@Sammaye Sammaye commented Feb 19, 2014

Ok so it is validation that you need support for.

One way which is not ideal is to create a setSettings function which makes a new model instance to validate from. So you would, in the setSettings function, add all your rules etc for the subdocument there.

Another way is, of course, for Yii2 to have something like a subdocument validator added. I made one for MongoYii it was ok.

@Sammaye
Copy link

@Sammaye Sammaye commented Feb 19, 2014

change that setsettings functin to a custom validation function in the model, sorry was thinking of something else there.

@mohorev
Copy link
Contributor Author

@mohorev mohorev commented Feb 19, 2014

Thank you, I know how to solve all these problems.
But all variants that exist were uncomfortable.

It would be great if this function will be implemented in the mongodb-extension.

@Sammaye
Copy link

@Sammaye Sammaye commented Feb 19, 2014

What would be a good variant for you?

I mean I am unsure of how Yii2 can support subdocuments outside of making a dedicated validator for it.

@mohorev
Copy link
Contributor Author

@mohorev mohorev commented Feb 19, 2014

I would like so:

$model = new MyCollection;
$subDocument = new MyGeneralSettings;
$subDocument->field1 = 10;
$subDocument->field2 = 30;

$model->name = 'Book';
$model->settings->general = $subDocument;
// OR
$model->settings->other = [
    'field2' => 'value1',
    'field3' => 'value2',
];
$model->random = 123456;

$model->validate();
$model->save();
@klimov-paul
Copy link
Member

@klimov-paul klimov-paul commented Feb 19, 2014

Such approach was implemented in following Yii1 extension:
https://github.com/canni/YiiMongoDbSuite

It allowed to work with sub-documents just as you have described.
However in practice it was almost unusable. It creates so many objects with cross-references, so they consumes too much memory and thier traversing on creation and saving of the document slows down the application dramatically some time.

You are still free to attempt repeating this approach - it should be possible with the current implementation.

@klimov-paul
Copy link
Member

@klimov-paul klimov-paul commented Feb 19, 2014

How can I make a form for making this record?

Are you sure there could be a single form for it? Creating sub-documents (netsed documents) assumes each of it maps to some isolated model. Practically it is rare (but of course still possible) situation someone may need to create form, which sets up all these models at once.

In general I advise do not use nested documents moving thier attributes at the top level of the document.
For example: instead of:

{
    comment: 'My comment',
    author: {
        name: John Smith,
        email: john.smith@domain.com,
    }
}

use following structure:

{
    comment: 'My comment',
    author_name: John Smith,
    author_email: john.smith@domain.com,
}

Note: It seems I have already posted this example somewhere, but can not find where exactly.

@klimov-paul
Copy link
Member

@klimov-paul klimov-paul commented Feb 19, 2014

Yes, found it: #2126 (comment)

@klimov-paul
Copy link
Member

@klimov-paul klimov-paul commented Feb 19, 2014

As I have already mentioned at #2126:

Yii Model designed assuming single attribute is a scalar. Validation and attribute processing based on this suggestion

I am afraid the core architcture prevents this issue to be implemented. Such attempt will produce code which will be inconsistent with other ActiveRecord libraries and will be too heavy and risk prone.

I am closing this one as duplicate of #2126

@Sammaye
Copy link

@Sammaye Sammaye commented Feb 19, 2014

Not completely, I mean Yii1 wass like this too but I still was able to implement: https://github.com/Sammaye/MongoYii/blob/master/validators/ESubdocumentValidator.php which was able to produce nested sets of rules for validation which would solve this issue

@Sammaye
Copy link

@Sammaye Sammaye commented Feb 19, 2014

Fair enough it's not the lightest library but could be made a lot better, in fact if I hadn't moved to Yii2 I would have considered it.

@klimov-paul
Copy link
Member

@klimov-paul klimov-paul commented Feb 19, 2014

As I said: everyone is free to compose his implenation for this feature, however this is not something, which Yii2 core can support, at least at present time.

@TheHett
Copy link

@TheHett TheHett commented Oct 29, 2014

@klimov-paul

Yes, found it: #2126 (comment)

Hi, This solution does not allow using array of subdocuments, e.g.:

{
    name: "ololosh",
    contacts: [{address: "..."}, {address: "..."}]
}

in other situation embed documents does not need, i think..

@Sammaye
Copy link

@Sammaye Sammaye commented Nov 8, 2014

If one were to make the capacity for this would they need to rewrite the Html class error sumary and the error handling functions on the model to do this right?

I am guessing that formatters etc would also need to be added to get this working in various parts of the framework?

What else is there?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
5 participants
You can’t perform that action at this time.