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

Comments

Projects
None yet
5 participants
@mohorev
Contributor

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

This comment has been minimized.

Show comment
Hide comment
@mitalcoi

mitalcoi Feb 19, 2014

Contributor

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

Contributor

mitalcoi commented Feb 19, 2014

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

@Sammaye

This comment has been minimized.

Show comment
Hide comment
@Sammaye

Sammaye 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.

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

This comment has been minimized.

Show comment
Hide comment
@mohorev

mohorev Feb 19, 2014

Contributor

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?

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@Sammaye

Sammaye 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 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

This comment has been minimized.

Show comment
Hide comment
@Sammaye

Sammaye Feb 19, 2014

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

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

This comment has been minimized.

Show comment
Hide comment
@mohorev

mohorev Feb 19, 2014

Contributor

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.

Contributor

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

This comment has been minimized.

Show comment
Hide comment
@Sammaye

Sammaye 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.

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

This comment has been minimized.

Show comment
Hide comment
@mohorev

mohorev Feb 19, 2014

Contributor

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();
Contributor

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

This comment has been minimized.

Show comment
Hide comment
@klimov-paul

klimov-paul Feb 19, 2014

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@klimov-paul

klimov-paul Feb 19, 2014

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@klimov-paul

klimov-paul Feb 19, 2014

Member

Yes, found it: #2126 (comment)

Member

klimov-paul commented Feb 19, 2014

Yes, found it: #2126 (comment)

@klimov-paul

This comment has been minimized.

Show comment
Hide comment
@klimov-paul

klimov-paul Feb 19, 2014

Member

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

Member

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

This comment has been minimized.

Show comment
Hide comment
@Sammaye

Sammaye 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 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

This comment has been minimized.

Show comment
Hide comment
@Sammaye

Sammaye 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.

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

This comment has been minimized.

Show comment
Hide comment
@klimov-paul

klimov-paul Feb 19, 2014

Member

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.

Member

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

This comment has been minimized.

Show comment
Hide comment
@TheHett

TheHett 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..

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

This comment has been minimized.

Show comment
Hide comment
@Sammaye

Sammaye 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?

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