Closed ctf0 closed 7 years ago
dates are stored as Mongodb UTCDateTime at the database.
When you request created_at attribute, Moloquent automatically converts that to a Carbon instance. However, you are overriding the default date mutator, hence $value
is an instance of MongoDB\BSON\UTCDateTime
not Carbon.
If you want, you can use $value->toDateTime()
which would return a PhP DateTime
object.
dd(Carbon::parse($value->toDateTime())->toDateTimeString());
Type error: DateTime::__construct() expects parameter 1 to be string, object given
to DateTime returns a native php DateTime
object. If you need to use Carbon you can write:
Carbon::instance($value->toDateTime())->toDateTimeString();
However, you do not need to convert it to Carbon, You can just use the native php method;
$value->toDateTime()->format('Y-m-d H:i:s');
@fuck yeaaaah 💃 , many thanx btw if its not to much to ask, am currently resolving the ManyToMany relation ids as objectId
but on the other side of the relation Moloquent saves the ids as string, is there anyway to check the type of field on the one side and save it the same on the other ?
Model\Post
public function tags()
{
return $this->belongsToMany(Tag::class);
}
Model\Tag
public function posts()
{
return $this->belongsToMany(Post::class);
}
on the posts collection
"tag_ids": [
ObjectId("580e15ef9a892011142f1efc")
]
on the tags collection
"article_ids": [
"580e15ed9a892011142f1b87",
]
you can always use php's function
is_a($value, "ObjectId");
However, I have a feeling that you are overcomplicating something here!! http://php.net/manual/en/function.is-a.php
no , am just trying to make the usage over mongo as similar to sql as possible,
if you have time check https://github.com/ctf0/MysqlToMongoDb i found away to update the field types b4 saving it to mongo as currently mongo doesnt support this even with $rename
which change the field name rather than its type ,
however from what i read that the objectId type is smaller in size than the string type, again as you are much more experienced in this than me so i thought i would ask u for guidance 😊
I'm not sure why would someone want Mongo to be similar to sql. The whole idea of NoSQL databases is that they are not similar to SQL. biggest advantage is embedding documents, which would be very difficult to automate for conversion.
Anyway, The idea of migrating a database by passing it through an ORM might not be the most efficient way to go through this since you you need to run a lot of code at high level for every entry. You probably noticed that you are having to resort to raw mongo driver commands anyway in many cases. So, if you decouple it from laravel, it would be faster and more useful to a wider audience. I haven't tried migrating a database from MySQL to mongo, but I've heard of some software called Mogofy that does it. you might want to peek at it.
With mongo you define the field type by inserting a field of the required type in the database there is no need to change type.
With ObjectId, my understanding is that it provides better performance on lower level because it is a hash. with a hash, the cpu can run a comparison in one cycle, while comparing a string would consume a cpu cycle per character.
similar means that on the high level u still do everything the same without caring what the under layer is , for example. driving a car, u still drive every car the same no matter if its a 1910 car or a 2025 hybrid.
i know about http://mongify.com/ but my experience with it didnt go as smooth as the site demo shows, also the reason i wanted to migrate from mysql to mongo is to ease the learning curve & so i can get as close as possible to a live copy of the code which uses mysql. that's why i built the package over laravel and not from scratch with plain php or even through the mongo shell.
am planning on using luman instead and wrap all of that in a one tiny app with node, so everyone can use it but not yet sure if this would work or not as i've never done that b4.
anyhow regarding the objectId , i've undone this part in the package so it follows the same pattern as moloquent but if you decided later to use it instead of string, i believe it would be better especially with large collections which using the objectId would make much more sense.
Since you do not have much data to move and you are happy to do it on high level, why don't you go all high. Stop worrying about the operation of the database and let Eloquent/Moloquent deal with it.
switch your BaseModel
to Moloquent and temporary set on it leave your default connection to mysql
class BaseModel extends Moloquent {
protected $primaryKey = 'id';
}
then your script can be as simple as
$models =['User','Post','Comment']
foreach($models as $model){
foreach($model::all() as $item){
$data = $item->getArray();
$newItem = new $model($data);
$newItem->old_id = $item->id;
$newItem->setKeyName('_id');
$newItem->setConnection('mongo');
$newItem->save();
}
}
don't forget to remove the setting of the primary key from your BaseModel before you switch your default connection.
WOOOOT :scream: , let me try that and get back to u
@iceheat
$models =['App\Http\Models\Role', 'App\Http\Models\Article', 'App\User'];
foreach($models as $model){
foreach($model::all() as $item){
$data = $item->getArray();
$newItem = new $model($data);
$newItem->old_id = $item->id;
$newItem->setKeyName('_id');
$newItem->setConnection('mongo');
$newItem->save();
}
}
Type error: Argument 1 passed to Moloquent\Query\Builder::__construct() must be an instance of Moloquent\Connection,
instance of Illuminate\Database\MySqlConnection given,
called in /home/vagrant/www/vendor/moloquent/moloquent/src/Eloquent/Model.php on line 549
Did you change your models to use moloquent first?
yeap :)
@ctf0 did you solve your last error "Argument 1 passed to Moloquent\Query..." ? i'm facing the same... :|
@Xplouder can u make a new ticket with the code used ?
the fields are saved as
doing something like
dd(Article::first()->created_at);
returnsetting the attr like
return
using the hack from https://github.com/jenssegers/date/issues/225 as
"@{$value}"
return"48576-12-03 21:46:40"