Sammaye/MongoYii

Many to many relations seem to be giving off wrong on condition

Closed this issue · 20 comments

Kuzdo commented

Hello Sammaye,
I need Your help again!

I have three models:

class Books extends EMongoDocument
{
    public $_id;
    public $name;
    public $authors;

    public function rules()
    {
        return array(
            /* ... */
            array('authors', 'subdocument', 'type' => 'many', 'class' => 'BooksAuthors')
        );
    }

    public function relations()
    {
        return array(
            'bookAuthors' => array('many', 'Authors', '_id', 'on' => 'authors')
        );
    }

}

class BooksAuthors extends EMongoModel
{
    public $id;

    public function rules()
    {
        return array(
            /* ... */
            array('id', 'required')
        );
    }

}

class Authors extends EMongoDocument
{
    public $_id;
    public $first_name;
    public $last_name;

    public function rules()
    {
        return array(
            /* ... */
        );
    }
}

And my collections looks like this:

Books:
{
  "_id" : ObjectId(),
  "name" : "Something",
  "authors" : [
    {
      "id" : "user1"
    },
    {
      "id" : "user2"
    }
  ]
}

Authors:
{
  "_id" : "user1",
  "first_name" : "Something",
  "last_name" : "Something"
}

To be clear, names of collections and fields are random, only for this question. I can't change structure of collections or names of fields.

In my Action I have this:

/* ... */

$this->book    = Books::model()->single($id)->findOne();
$this->authors = $this->book->bookAuthors;

/* ... */

$this->controller->render('view', array(
    'id'      => $id,
    'model'   => $this->book,
    'authors' => $this->authors
));

And in view var_dump($authors);
And result is: array (size=0) empty

Can You help me?

Kuzdo commented

I forgot to write, that I have turn on query log in mongo (db.setLogLevel(1, 'query')) and this is result:

2016-02-04T08:32:20.444+0100 I QUERY    [conn8] query my_db.books   query: { my_custom_id: { $eq: 1 } } planSummary: COLLSCAN ntoskip:0 nscanned:0 nscannedObjects:1 keyUpdates:0 writeConflicts:0 numYields:0 nreturned:1 reslen:247 locks:{ Global: { acquireCount: { r: 2 } }, MMAPV1Journal: { acquireCount: { r: 1 } }, Database: { acquireCount: { r: 1 } }, Collection: { acquireCount: { R: 1 } } } 0ms

2016-02-04T08:32:20.500+0100 I QUERY    [conn8] query my_db.authors query: { $query: { _id: { $in: [ { id: "user1" }, { id: "user2" } ] } }, $orderby: [] } planSummary: IXSCAN { _id: 1 } ntoreturn:0 ntoskip:0 nscanned:0 nscannedObjects:0 keyUpdates:0 writeConflicts:0 numYields:0 nreturned:0 reslen:20 locks:{ Global: { acquireCount: { r: 2 } }, MMAPV1Journal: { acquireCount: { r: 1 } }, Database: { acquireCount: { r: 1 } }, Collection: { acquireCount: { R: 1 } } } 0ms
Kuzdo commented

Ok, there was no question. Answer is in documentation:

The onclause supports multiple field types. It can take a DBRefor an ObjectIdor an array of ObjectIds depending on how you define your document.

This sounds like a failure with string PKs then

Kuzdo commented

I don't know, I was trying few ways, and always result was the same. I changed my mind, and I created custom method to retrieve this data without relations.

Kuzdo commented

I was debugging it, and $pk was an array of arrays:

array(
    array('id' => 'user1'),
    array('id' => 'user2')
)

Seems it is not merging the keys correctly for some reason

Kuzdo commented

If you can check it what can be wrong, that would be great, but I know that there is Yii 2, and this isn't too important, so for now I'm using custom method ;) But despite this I am very grateful for this extension 👍

I will look into it, this ext is still widely used and this is a bug

Kuzdo commented

Thanks for everything :) I'll be watching :)

This is definitely something with string PKs. I have got round to setting this up after some busy time and it works perfect for MongoIds so this is definitely about data type

Ok this is a little weird, mine works. I just went into my Wiki test app and changed the user to have string _ids and liked an article multiple times and it does the join perfectly

Can you show your document structure from the database?

Sorry I see now, you did add it

So it is actually structure, it is actually having a row to each

Yeah, this is a hard one since it requires me understanding your custom structure. Maybe adding the ability to use object notation in the relation definition, hmmm

Can you try this commit a sec: 8af163d ?

I think I have been able to test this actually so I am going to close this now

Kuzdo commented

Sorry for late responding. Yes, now it is working! Thanks again for help :) 👍

Awesome sauce, thanks!