1

I have a post documents that schema looks like

    {
        "author": {
            "name": "John",
            "gender": 0
        },
        "stats": {
            "likes": 0
        },
        "content": "The new post",
        "updated_at": "2017-06-05 15:15:21",
        "created_at": "2017-06-04 18:10:30",
    }

How can I update the stats.likes field through jenssegers/laravel-mongodb

According to the GitHub page, There are a method increment() that can be used. So I was trying this way

Post::findOrFail( $request->id )->increment('stats.likes');

But got

ErrorException in HasAttributes.php line 906:
Undefined index: stats.likes

However, with the mongo shell, it can work at the code

db.posts.update( { '_id': ObjectId('5933dc7d4abcf141956a6250') }, { '$inc': { 'stats.likes': 1 } )  )

Is that an error caused by nested object?

According to the source code, I found

/**
 * @inheritdoc
 */
public function increment($column, $amount = 1, array $extra = [], array $options = [])
{
    $query = ['$inc' => [$column => $amount]];

    if (! empty($extra)) {
        $query['$set'] = $extra;
    }

    // Protect
    $this->where(function ($query) use ($column) {
        $query->where($column, 'exists', false);

        $query->orWhereNotNull($column);
    });

    return $this->performUpdate($query, $options);
}

If I'm not wrong, the field name stats.likes will pass to the shell directly at the 1st parameter of the method. Why it can just work with the command line?

  • MongoDB 3.4
  • jenssegers/laravel-mongodb 3.2
  • Laravel 5.4

1 Answer 1

3

Since I can update a nested object through the artisan command, I wrote a raw expression below alternatively:

$result = Post::raw(function($collection) use ($request){

    return $collection->findOneAndUpdate([
        '_id' => new \MongoDB\BSON\ObjectID ($request->_id),
    ], [ '$inc' => [ 'stats.likes' => 1 ] ] );

});

Notice that you may have effect with db.articles.update(), but the Mongo\Collection doesn't have a method named update(), use findOneAndUpdate, or others instead. (UpdateMany, UpdateOne)

And if the where condition contains _id, you have to wrap your id variable with \MongoDB\BSON\ObjectID object in the case of raw expression.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.