MongoDB 条件操作符
Exists(判断字段是否存在)
查询所有存在age字段的记录
User::where('age', 'exists', true)->get();
查询所有不存在name字段的记录
User::where('age', 'exists', false)->get();
All(匹配所有)
这个操作符跟SQL语法的in类似,但不同的是, in只需满足( )内的某一个值即可,而$all必须满足[ ]内的所有值
User::where('roles', 'all', ['moderator', 'author'])->get();
Size(数组元素个数)
对于查询数组来说是非常有用的,顾名思义,可以用它查询特定长度的数组。
User::where('tags', 'size', 3)->get();
Regex(正则表达式匹配)
选择值与指定正则表达式匹配的文档。
User::where('name', 'regex', new \MongoDB\BSON\Regex("/.*doe/i"))->get();
注意:您也可以使用Laravel正则表达式操作。 这些更灵活,会自动将正则表达式字符串转换为MongoDB \ BSON \ Regex对象。
User::where('name', 'regexp', '/.*doe/i'))->get();
反之:
User::where('name', 'not regexp', '/.*doe/i'))->get();
Type(类型)
User::where('age', 'type', 2)->get();
Mod(取模运算)
查询age取模10等于0的数据
User::where('age', 'mod', [10, 0])->get();
Near(指定地理空间查询从最近到最远返回文档的点。)
$ near运算符可以指定GeoJSON点或传统坐标点。
$users = User::where('location', 'near', [
'$geometry' => [
'type' => 'Point',
'coordinates' => [
-0.1367563,
51.5100913,
],
],
'$maxDistance' => 50,
]);
GeoWithin(选择具有完全在指定形状内的地理空间数据的文档。)
$users = User::where('location', 'geoWithin', [
'$geometry' => [
'type' => 'Polygon',
'coordinates' => [[
[-0.1450383,51.5069158,],
[-0.1367563,51.5100913,],
[-0.1270247,51.5013233,],
[-0.1450383,51.5069158,],
]],
],
]);
GeoIntersects(选择地理空间数据与指定GeoJSON对象相交的文档;即数据和指定对象的交集是非空的。)
$locations = Location::where('location', 'geoIntersects', [
'$geometry' => [
'type' => 'LineString',
'coordinates' => [
[-0.144044,51.515215,],[-0.129545,51.507864,],
],
],
]);
Where
匹配满足JavaScript表达式的文档。 有关更多信息,请查看 http://docs.mongodb.org/manual/reference/operator/query/where/#op._S_where
Inserts, updates and deletes
插入,更新和删除记录就像原始的Eloquent一样。
通过模型插入数据
$user = new User;
$user->name = 'John';
$user->save();
您还可以使用create方法将新模型保存在一行中:
User::create(['name' => 'John']);
通过模型更新数据
要更新模型,您可以检索它,更改属性并使用save方法。
$user = User::first();
$user->email = 'john@foo.com';
$user->save();
通过模型删除数据
要删除模型,只需在实例上调用delete方法:
$user = User::first();
$user->delete();
或者通过主键删除
User::destroy('517c43667db388101e00000f');
Dates
Eloquent允许您使用Carbon / DateTime对象而不是MongoDate对象。 在内部,这些日期在保存到数据库时将转换为MongoDate对象。 如果您希望在非默认日期字段中使用此功能,则需要按照此处所述手动指定它们:http://laravel.com/docs/eloquent#date-mutators
示例:
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class User extends Eloquent {
protected $dates = ['birthday'];
}
Which allows you to execute queries like:
$users = User::where('birthday', '>', new DateTime('-18 years'))->get();
MongoDB 关系
MongoDB的关系表示多个文档之间在逻辑上的相互联系文档间可以通过嵌入和引用来建立联系。
支持的关系有:
* hasOne
* hasMany
* belongsTo
* belongsToMany
* embedsOne
* embedsMany
示例:
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class User extends Eloquent {
public function items(){
return $this->hasMany('Item');
}
}
和反比关系:
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Item extends Eloquent {
public function user(){
return $this->belongsTo('User');
}
}
belongsToMany关系不会使用数据透视表“table”,而是将id推送到related_ids属性。 这使belongsToMany方法的第二个参数无用。 如果要为关系定义自定义键,请将其设置为null:
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class User extends Eloquent {
public function groups(){
return $this->belongsToMany('Group', null, 'user_ids', 'group_ids');
}
}
其他关系尚未得到支持,但未来可能会增加。 在http://laravel.com/docs/eloquent#relationships上阅读有关这些关系的更多信息
EmbedsMany Relations
如果要嵌入模型而不是引用它们,可以使用embedsMany关系。 此关系类似于hasMany关系,但将模型嵌入父对象中。
记住:这些关系返回Eloquent集合,它们不返回查询构建器对象!
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class User extends Eloquent {
public function books(){
return $this->embedsMany('Book');
}
}
您可以通过动态属性访问嵌入式模型:
$books = User::first()->books;
反向关系是自动可用的,您无需定义此反向关系。
$user = $book->user;
插入和更新嵌入式模型的工作方式与hasMany关系类似:
$book = new Book(['title' => 'A Game of Thrones']);
$user = User::first();
$book = $user->books()->save($book);
// or
$book = $user->books()->create(['title' => 'A Game of Thrones'])
您可以使用其保存方法更新嵌入式模型(从2.0.0版开始提供):
$book = $user->books()->first();
$book->title = 'A Game of Thrones';
$book->save();
您可以通过在关系上使用destroy方法或模型上的delete方法(从2.0.0版开始提供)来删除嵌入式模型:
$book = $user->books()->first();
$book->delete();
// or
$user->books()->destroy($book);
如果要在不触及数据库的情况下添加或删除嵌入式模型,可以使用关联和分离方法。 要最终将更改写入数据库,请保存父对象:
$user->books()->associate($book);
$user->save();
与其他关系一样,embedsMany根据模型名称假定关系的本地键。 您可以通过将第二个参数传递给embedsMany方法来覆盖默认本地键:
return $this->embedsMany('Book', 'local_key');
嵌入式关系将返回嵌入式项的集合,而不是查询构建器。 查看可用的操作:https://laravel.com/docs/master/collections
EmbedsOne Relations
embedsOne关系类似于embedsMany关系,但只嵌入单个模型。
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Book extends Eloquent {
public function author(){
return $this->embedsOne('Author');
}
}
您可以通过动态属性访问嵌入式模型:
$author = Book::first()->author;
插入和更新嵌入式模型的工作方式与hasOne关系类似:
$author = new Author(['name' => 'John Doe']);
$book = Books::first();
$author = $book->author()->save($author);
// or
$author = $book->author()->create(['name' => 'John Doe']);
您可以使用以下新模型替换嵌入式模型:
$author = $book->author;
$author->name = 'Jane Doe';
$author->save();
您可以使用以下新模型替换嵌入式模型:
$newAuthor = new Author(['name' => 'Jane Doe']);
$book->author()->save($newAuthor);
MySQL关系
如果您正在使用混合MongoDB和SQL设置,那么您很幸运! 模型将根据相关模型的类型自动返回MongoDB或SQL关系。 当然,如果您希望此功能双向工作,则您的SQL模型将需要使用Jenssegers \ Mongodb \ Eloquent \ HybridRelations特性。 请注意,此功能仅适用于hasOne,hasMany和belongsTo关系。
示例基于SQL的用户模型:
use Jenssegers\Mongodb\Eloquent\HybridRelations;
class User extends Eloquent {
use HybridRelations;
protected $connection = 'mysql';
public function messages(){
return $this->hasMany('Message');
}
}
而基于Mongodb的Message模型:
use Jenssegers\Mongodb\Eloquent\Model as Eloquent;
class Message extends Eloquent {
protected $connection = 'mongodb';
public function user(){
return $this->belongsTo('User');
}
}
原始表达
这些表达式将直接注入查询中。
User::whereRaw(['age' => array('$gt' => 30, '$lt' => 40)])->get();
您还可以在内部MongoCollection对象上执行原始表达式。 如果在模型类上执行此操作,它将返回一组模型。 如果在查询构建器上执行此操作,它将返回原始响应。
//返回用户模型的集合。
$models = User::raw(function($collection){
return $collection->find();
});
//返回原始的MongoCursor。
$cursor = DB::collection('users')->raw(function($collection){
return $collection->find();
});
可选:如果未将闭包传递给raw方法,则可以访问内部MongoCollection对象:
$model = User::raw()->findOne(['age' => array('$lt' => 18)]);
可以像这样访问内部MongoClient和MongoDB对象:
$client = DB::getMongoClient();
$db = DB::getMongoDB();
MongoDB 具体操作
超时
要防止MongoCursorTimeout异常,您可以手动设置将应用于游标的超时值:
DB::collection('users')->timeout(-1)->get();
Upsert是一种特殊的更新方式,要是没有找到符合条件的文档,则会自动创建一个文档,否则更新对应的文档数据。
看 mongodb权威指南提到 upsert会避免竞态问题,如果使用日常的思维去考虑这个问题,需要先去数据库中查找符合条件的文档,然后再根据更新信息更新数据,这个在多线程或者多进程的情况下产生资源竞争的情况,使用 upsert可以很好的避免这种情况的发
DB::collection('users')->where('name', 'John')
->update($data, ['upsert' => true]);
Projections(投影文档)
您可以使用项目方法将投影应用于查询。
value字段的取值为0或者false时,表示要在返回结果中去除该字段;如果value字段取值为1或者true,表示在返回结果中需要包含这个字段。
查询结构只展示title和likes
$project = ['title'=>1,'likes'=>1,"_id"=>0];
DB::collection('users')->project($project)->get();
DB::collection('items')->project(['tags' => ['$slice' => 1]])->get();
DB::collection('items')->project(['tags' => ['$slice' => [3, 7]]])->get();
分页使用
$limit = 25;
$projections = ['id', 'name'];
DB::collection('items')->paginate($limit, $projections);
Push(更新数组$push操作符)
$push操作符添加指定的值到数组中,$push操作符有如下的格式:
DB::collection('users')->where('name', 'John')->push('items', 'boots');
DB::collection('users')->where('name', 'John')->push('messages', ['from' => 'Jane Doe', 'message' => 'Hi John']);
如果您不想要重复项,请将第三个参数设置为true:
DB::collection('users')->where('name', 'John')->push('items', 'boots', true);
Pull(更新数组$pull修饰符)
$pull修饰符会删除掉数组中符合条件的元素
DB::collection('users')->where('name', 'John')->pull('items', 'boots');
DB::collection('users')->where('name', 'John')->pull('messages', ['from' => 'Jane Doe', 'message' => 'Hi John']);
Unset(删除一个指定的字段)
如果指定的字段不存在则操作不做任何处理;
当使用$操作符匹配任何数组元素,$unset替换指定的元素为null而不是删除掉指定的元素,此行为保持数组大小和位置一直;
从文档中删除一个或多个字段。
DB::collection('users')->where('name', 'John')->unset('note');
您还可以在模型上执行取消设置。
$user = User::where('name', 'John')->first();
$user->unset('note');
查询缓存
您可以使用remember方法轻松缓存查询结果:
$users = User::remember(10)->get()
参考: http://laravel.com/docs/queries#caching-queries
查询记录
默认情况下,Laravel会记录已为当前请求运行的所有查询的内存。 但是,在某些情况下,例如插入大量行时,这可能会导致应用程序使用过多的内存。 要禁用日志,可以使用disableQueryLog方法:
DB::connection()->disableQueryLog();
网友评论