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

Parent/Child-Relationships #115

Closed
ArjanQside opened this issue Nov 23, 2016 · 3 comments
Closed

Parent/Child-Relationships #115

ArjanQside opened this issue Nov 23, 2016 · 3 comments

Comments

@ArjanQside
Copy link

Hello guys,

I have a problem with the _routing field in ElasticSearch. I'll explain step by step my code and I hope there is someone who can help me out.

Mapping

At first I create my Mapping in ElasticSearch. (My index and type)
My index is 'books' and my types are 'book' and 'chapter'.
I make this index with the following code:

PUT /books
{
   "mappings": {
      "book": {
         "properties": {
            "title": {
               "type": "string"
            },
            "nur": {
               "type": "integer"
            },
	    "isbn": {
               "type": "long"
            },
	    "publication_year": {
               "type": "integer"
            },
	    "publisher": {
               "type": "string"
            },
	    "author": {
               "type": "string"
            },
	    "synopsis": {
               "type": "string"
            },
	    "print_year": {
               "type": "integer"
            },
	    "created_by": {
               "type": "integer"
            },
	    "last_updated_by": {
               "type": "integer"
            },
	    "create_date": {
               "type": "date",
	       "format": "yyy-MM-dd HH:mm:ss"
            },
	    "update_date": {
               "type": "date",
	       "format": "yyy-MM-dd HH:mm:ss"
            }
         }
      },
      "chapter": {
         "_parent": {
            "type": "book"
         },
         "properties": {
            "title": {
               "type": "string"
            },
            "start_page_print": {
               "type": "integer"
            },
            "end_page_print": {
               "type": "integer"
            },
            "start_page_hocr": {
               "type": "integer"
            },
            "end_page_hocr": {
               "type": "integer"
            },
            "created_by": {
               "type": "integer"
            },
    	    "last_updated_by": {
               "type": "integer"
            },
	    "create_date": {
               "type": "date",
	       "format": "yyy-MM-dd HH:mm:ss"
            },
	    "update_date": {
               "type": "date",
	       "format": "yyy-MM-dd HH:mm:ss"
            }
         }
      }
   }
}

As you can see, there is a parent-child relationship between a book and chapter. Type 'chapter' has a _parent, which is type 'book'.

My Yii Models

I've created a Yii2 Models of ElasticSearch.
This is how my "Book" model looks:

<?php
    
namespace common\models;

use Yii;

class Book extends \yii\elasticsearch\ActiveRecord
{
    public static function index(){
        return "books";
    }
    
    public static function type(){
        return "book";
    }
    
    public function attributes()
    {
        return [
            'id',
            '_id',
            '_index',
            '_type',
            '_score',
            'author', 
            'title', 
            'nur', 
            'isbn', 
            'publication_year', 
            'publisher', 
            'synopsis', 
            'print_year', 
            'create_date', 
            'update_date', 
            'created_by', 
            'last_updated_by'
        ];
    }
    
    public function attributeLabels()
    {
        return [
            'author' => 'Author',
            'title' => 'Title',
            'nur' => 'Nur',
            'isbn' => 'ISBN',
            'publication_year' => 'Publication Year',
            'Publisher' => 'Publisher',
            'synopsis' => 'Synopsis',
            'print_year' => 'Print Year',
            'create_date' => 'Create Date',
            'update_date' => 'Update Date',
            'created_by' => 'Created By',
            'last_updated_by' => 'Last Updated By'
        ];
    }
}

My "Chapter" model look like this:

<?php

namespace common\models;

use Yii;

class Chapter extends \yii\elasticsearch\ActiveRecord
{
    public static function index(){
        return 'books';
    }
    
    public static function type(){
        return "chapter";
    }
    
    public function attributes()
    {
        return [
            '_id',
            '_index',
            '_type',
            '_score',
            '_parent',
            'id_parent_helper',
            '_routing',
            'title', 
            'start_page_print', 
            'end_page_print', 
            'start_page_hocr', 
            'end_page_hocr', 
            'create_date', 
            'update_date', 
            'created_by', 
            'last_updated_by'
        ];
    }

    /**
     * @inheritdoc
     */
    public function attributeLabels()
    {
        return [
            'title' => 'Title',
            'start_page_print' => 'Start Page Print',
            'end_page_print' => 'End Page Print',
            'start_page_hocr' => 'Start Page Hocr',
            'end_page_hocr' => 'End Page Hocr',
            'create_date' => 'Create Date',
            'update_date' => 'Update Date',
            'created_by' => 'Created By',
            'last_updated_by' => 'Last Updated By',
        ];
    }
}

Creating, updating and deleting a book

I have an action in the BookController called "actionCreate()" for creating a book, "actionUpdate()" for updating a book and "actionDelete()" for deleting a book.

The parameter $id is the Primary Key ( _id ) of the book.

The code looks as the following:

public function actionCreate()
    {
        $model = new Book();
        
        $postdata = Yii::$app->request->post();
        
        if($postdata) {
            $model = new Book();
            $model->title = $postdata['Book']['title'];
            $model->author = $postdata['Book']['author'];
            $model->nur = intval($postdata['Book']['nur']);
            $model->isbn = intval($postdata['Book']['isbn']);
            $model->publication_year = intval($postdata['Book']['publication_year']);
            $model->publisher = $postdata['Book']['publisher'];
            $model->synopsis = $postdata['Book']['synopsis'];
            $model->print_year = intval($postdata['Book']['print_year']);
            $model->created_by = Yii::$app->user->getId();
            $model->last_updated_by = Yii::$app->user->getId();
            $model->create_date = date("Y-m-d H:i:s");
            $model->update_date = date("Y-m-d H:i:s");
            
            if($model->save()) {
                if($model->save()){
                    sleep(1);
                    return $this->redirect(['index']);
                }
            }
        }
        else {
            return $this->render('create', [
                'model' => $model,
            ]);
        }
    }

public function actionUpdate($id)
    {
        $model = Book::get($id);
        
        $postdata = Yii::$app->request->post();
        
        if($postdata) {
            $model->title = $postdata['Book']['title'];
            $model->author = $postdata['Book']['author'];
            $model->nur = intval($postdata['Book']['nur']);
            $model->isbn = intval($postdata['Book']['isbn']);
            $model->publication_year = intval($postdata['Book']['publication_year']);
            $model->print_year = intval($postdata['Book']['print_year']);
            $model->publisher = $postdata['Book']['publisher'];
            $model->synopsis = $postdata['Book']['synopsis'];
            $model->update_date = date('Y-m-d H:i:s');
            $model->last_updated_by = Yii::$app->user->getId();
            
            if($model->save()) {
                sleep(1);
                return $this->redirect(['view', 'id' => $model->getPrimaryKey()]);
            }
            
        }
        else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }

public function actionDelete($id)
    {
        $model = Book::get($id);
        if ($model->delete()){
            sleep(1);
            return $this->redirect(['index']);
        }
    }

Creating a chapter

In my ChapterController do I have an action called "actionCreate()" to make a chapter.
The model of Chapter has an "id_parent_helper". Which can be set in the create form, when I make a chapter. This field is the id_parent of the chapter.

The code look as following:

public function actionCreate()
    {
        $model = new Chapter();
        $postdata = Yii::$app->request->post();
        
        if($postdata) {
            if(isset($postdata['Chapter']['id_parent_helper'])) {
                //find a book
                $book = Book::get($postdata['Chapter']['id_parent_helper']);
            }
            $query = Yii::$app->elasticsearch->createCommand()->insert('books', 'chapter', [
                "title" => strval($postdata['Chapter']['title']),
                "start_page_print" => intval($postdata['Chapter']['start_page_print']),
                "start_page_hocr" => intval($postdata['Chapter']['start_page_hocr']),
                "end_page_print" => intval($postdata['Chapter']['end_page_print']),
                "end_page_hocr" => intval($postdata['Chapter']['end_page_hocr']),
                "create_date" => date("Y-m-d H:i:s"),
                "update_date" => date("Y-m-d H:i:s"),
                "created_by" => 11,
                "last_updated_by" => 11
            ], null, ['parent' => $book->getPrimaryKey()]);
            
            if($query){
                sleep(1);
                return $this->redirect(['index']);
            }
        }
        else {
            return $this->render('create', [
                'model' => $model,
            ]);
        }
    }

Updating a chapter

In my ChapterController do I have an action called "actionUpdate()" to update a chapter.
The parameter $id is the Primary Key of the chapter you want to update.
As you can see I have to set the "routing". When I dont set the "routing" then i'll get the error:
"routing_missing_exception".

"Routing" is now an _id of a book, which one is the parent of this chapter.
Later I have to set this routing automaticly.

The code look as following:

public function actionUpdate($id)
    {
        $model = Chapter::get($id,['routing' => 'AViQ40WP_GuJzV_k9tpa']);
        $postdata = Yii::$app->request->post();
        
        if($postdata) {
            $model->title = $postdata['Chapter']['title'];
            $model->start_page_print = intval($postdata['Chapter']['start_page_print']);
            $model->start_page_hocr = intval($postdata['Chapter']['start_page_hocr']);
            $model->end_page_print = intval($postdata['Chapter']['end_page_print']);
            $model->end_page_hocr = intval($postdata['Chapter']['end_page_hocr']);
            $model->update_date = date('Y-m-d H:i:s');
            $model->last_updated_by = Yii::$app->user->getId();
            
            if($model->update(true, null, ['routing' => 'AViQ40WP_GuJzV_k9tpa'])) {
                sleep(1);
                return $this->redirect(['index']);
            }
            
        }
        else {
            return $this->render('update', [
                'model' => $model,
            ]);
        }
    }

The end

Do I create my models on the right way? Do I have my code right? Do I have to set the routing value? And what is exactly the meaning of this Routing field?

I'm creating a chapter with Yii::$app->elasticsearch->createCommand()->insert.
Is there an other way to create a chapter? (With a parent-child relationship)

I know there is in Yii2 with MySQL an easy when for creating something.
This is like:

$chapter = new Chapter();

$chapter->title = "Title";
$chapter->start_page_print = 10;
$chapter->start_page_hocr = 20;
$chapter->end_page_print = 15;
$chapter->end_page_hocr = 30;

if ($chapter->save()) {
     return $this->redirect(['index']);
}

Is this also possible for parent-child relationships in ElasticSearch?

I'm very confused and I hope there is someone who can help me out and can bring my brain on the right way!

Kind regards,

Arjan

@cebe
Copy link
Member

cebe commented Nov 23, 2016

how is this different from what you have posted in #114?

@ArjanQside
Copy link
Author

@cebe: I just want to know, if I'm doing this on the right way, because I always get the error "routing_missing_exception". So this is not completely the same topic as the other post.

@cebe
Copy link
Member

cebe commented Nov 25, 2016

You have to specify the routing as I have explained here: #114 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants