Рассмотрим следующую коллекцию,
{
"_id": ObjectId("545c535e75de3e630c8b4567"),
"tables" : [
{
"_id" : ObjectId("54584f5975de3e040fe97319"),
"title" : "001",
},
{
"_id" : ObjectId("54584fb175de3e1c0fe97319"),
"title" : "002",
}
]
}
Мне нужно извлечь данные из этой коллекции, где tables.title = «001». Я использовал каркас Laravel. Я пробовал следующие коды, но не работал должным образом. Если у кого-то есть идея, чтобы решить эту проблему, пожалуйста, помогите мне.
DB::connection($this->connection)->collection($this->collection)->where('tables','elemMatch',array('title'=>"001"))->get();
DB::connection($this->connection)->collection($this->collection)->where('tables.title',"001")->get();
DB::connection($this->connection)->collection($this->collection)->where('tables.$.title',"001")->get();
Для «единичных» матчей вы должны просто использовать проекции:
$result = DB::collection('collection')->where(
'tables.title', '001'
)->project(array( 'tables.$' => 1 ) )->get();
Для множественных совпадений вам понадобится доступ к «необработанным» объектам драйвера, чтобы «фильтровать» содержимое массива, так как для этого нужна структура агрегации. Вы можете сделать это так:
# Returns the original Mongo Result
$result = DB::collection('collection')->raw(function($collection)
{
return $collection->aggregate(array(
# Match the documents containing the matching elements first
array(
'$match' => array( 'tables.title' => '001' )
),
# Unwind the array to "de-normalize"array( '$unwind' => '$tables' ),# Match again to "filter" the now "de-normalized" documents
array(
'$match' => array( 'tables.title' => '001' )
),
# Construct back as an array
array(
'$group' => array(
'_id' => '$_id',
'tables' => array(
'$push' => '$tables'
)
)
)
));
});
Следующая агрегация может решить вашу проблему,
db.collectionName.aggregate({"$unwind":"$tables"},{"$project":{"title":"$tables.title","id":"$tables._id","_id":0}},{"$match":{"title":"001"}})
Это возвращаемый заголовок и идентификатор совпадающего заголовка