yii2-elasticsearch icon indicating copy to clipboard operation
yii2-elasticsearch copied to clipboard

routing_missing_exception when update/delete data.

Open ArjanQside opened this issue 8 years ago • 8 comments

Hello guys,

What steps will reproduce the problem?

When I go to my website to a CRUD and want to update a row of a chapter, and press on "UPDATE" to save the data, there will come an routing_missing_exception error of ElasticSearch. For deleting it is exactly the same thing.

What's expected?

Saved data, redirect to the index page.

What do you get instead?

ElasticSearch error: Routing_missing_exception Screenshot: http://i68.tinypic.com/6gzclv.png

Additional info

I'm using parent-child relationship. I got books with chapters I can create, update and delete a book, without any errors. So I only got this when I try to update/delete a chapter.

My code to create a chapter:

public function actionCreatechapter($id_parent)
    {
        $chaptermodel = new Chapter();
        $postdata = Yii::$app->request->post();
        
        if($postdata) {
            $book = Book::findOne(['id' => $id_parent]);
            $pkofbook = $book->getPrimaryKey();
            
            $query = Yii::$app->elasticsearch->createCommand()->insert('books', 'chapters', [
                "id" => $postdata['Chapter']['id'],
                "id_parent" => $pkofbook,
                "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
            ], $pkofbook, ['parent' => $pkofbook]);
            
            if($query){
                return $this->redirect(['index']);
            }
        }
        else {
            return $this->render('createchapter', [
                'chaptermodel' => $chaptermodel,
                'id_parent' => $id_parent,
            ]);
        }
    }

My code to update a chapter:

public function actionUpdatechapter($id)
{
        $chaptermodel = Chapter::findOne(['id' => $id]);
        
        $pk = $chaptermodel->getPrimaryKey();
        
        $postdata = Yii::$app->request->post();
        
        if($postdata) {
            $chaptermodel::get($pk);

            $chaptermodel->id = intval($postdata['Chapter']['id']);
            $chaptermodel->title = $postdata['Chapter']['title'];
            $chaptermodel->start_page_print = $postdata['Chapter']['start_page_print'];
            $chaptermodel->end_page_print = intval($postdata['Chapter']['end_page_print']);
            $chaptermodel->start_page_hocr = intval($postdata['Chapter']['start_page_hocr']);
            $chaptermodel->end_page_hocr = intval($postdata['Chapter']['end_page_hocr']);
            
            $chaptermodel->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(['index']);
            }
            
        }
        else {
            return $this->render('updatechapter', [
                'chaptermodel' => $chaptermodel,
            ]);
        }
    }

Kind Regards, Arjan

ArjanQside avatar Nov 21 '16 14:11 ArjanQside

When you have declared a parent/child relationsship you must provide a routing parameter when you call update() or delete() on a record and provide the parent id, so elasticsearch knows in which shard to look for the data to update.

The code should look like this:

$chapter->update(true, null, ['routing' => $book->id]);

See https://www.elastic.co/guide/en/elasticsearch/guide/current/indexing-parent-child.html on more details about this. And http://www.yiiframework.com/doc-2.0/yii-elasticsearch-activerecord.html#update%28%29-detail for the description of the $options parameter of update().

cebe avatar Nov 21 '16 20:11 cebe

@cebe : How can I get a routing value of a record in this extension? I mean the routing value, which I don't know.

For PK's there is $model->getPrimaryKey(). Is there something for the routing value?

ArjanQside avatar Nov 29 '16 14:11 ArjanQside

the routing value usually is the PK. At least as far as I know. Is that not the case for you?

cebe avatar Nov 29 '16 17:11 cebe

I got it.

Now I need to find chapters by the Routing value.

In ElasticSearch I use the next code to search by its Routing value:

GET /books/chapter/_search?routing=AVjyS1wf_GuJzV_k9ttq
{
    "query" : { 
        "match_all" : {
            
        } 
    }
}

In my Yii code I'm trying to do this as following: $chapters = Chapter::get(null, ['routing' => $id]);

  • $id is the routing value

This will return NULL.

Can anyone help me?

ArjanQside avatar Dec 12 '16 09:12 ArjanQside

Could be related to #99.

beowulfenator avatar Jul 15 '20 09:07 beowulfenator

Hi, I have a problem, I want to query child condition, I fave found it only use query() or where(), but they cannot be used at the same time. What should i do?

huangli58 avatar Jul 16 '20 01:07 huangli58

Can't help you with child conditions specifically, because I've never used them. However, query() and where() now work together (as of this commit: https://github.com/yiisoft/yii2-elasticsearch/commit/7205fafe2575963ffd625775bafe82551c73ec98). There's even a test for it:

public function testQueryWithWhere()
{
    // make sure that both `query()` and `where()` work at the same time
    $query = new Query();
    $query->from('query-test', 'user');
    $query->where(['status' => 2]);
    $query->query(['term' => ['name' => 'userb']]);
    $result = $query->search($this->getConnection());

    $total = is_array($result['hits']['total']) ? $result['hits']['total']['value'] : $result['hits']['total'];
    $this->assertEquals(1, $total);
}

This definitely works.

beowulfenator avatar Jul 16 '20 08:07 beowulfenator

@beowulfenator

Can't help you with child conditions specifically, because I've never used them. However, query() and where() now work together (as of this commit: 7205faf). There's even a test for it:

public function testQueryWithWhere()
{
    // make sure that both `query()` and `where()` work at the same time
    $query = new Query();
    $query->from('query-test', 'user');
    $query->where(['status' => 2]);
    $query->query(['term' => ['name' => 'userb']]);
    $result = $query->search($this->getConnection());

    $total = is_array($result['hits']['total']) ? $result['hits']['total']['value'] : $result['hits']['total'];
    $this->assertEquals(1, $total);
}

This definitely works.

Yes, Thank you , I update my package, that query and where can already coexist. This change is beautiful.

huangli58 avatar Jul 16 '20 08:07 huangli58