Yêu cầu thg 7 31, 2018 7:31 SA• 4215 0 0
Chào mọi người. Mình có 1 app đang làm sử dụng mongodb. Do mới tiếp xúc nên có vấn đề mình gặp phải cần mọi người trợ giúp.
Mình có 3 model liên quan cụ thể các field phía dưới. Từ Model Review, mình muốn lấy toàn bộ reviews của Book. router api dạng: domain/book_id/reviews. Mỗi review sẽ có comments nên get luôn các comment của review tương ứng[ và info tác giả của comment đó]. Trong từng comment có trường user_id. Ở đây mình dùng các table riêng biệt.
Lúc trước minh dùng foEarch lấy ra từng ID rồi truy vấn để lấy thông tin. Nhưng thấy nó Load mất thời gian. Sau đó thì tìm hiểu đc cái lookup và populate này.
Mình dùng câu truy vấn như này ở Model review.
async testLookup[book_id, limit, page]{
return await Review.aggregate[[
{ $match: { "book_id": new mongoose.Types.ObjectId[book_id]} },
{ $lookup: {
from: 'comments',
localField: '_id',
foreignField: 'review_id',
as: 'comments'
}},
]];
}
Kết quả sẽ ra được như thế này. Mình muốn là ở cái user_id sẽ hiển thị Object thông tin User đó luôn. Kiểu như bình thường sử dụng populate thì sẽ là Comment.user_id ấy.
[ "user_id": {
"_id": "5b4f090bbcb0521b24759a9c",
"email": "",
"is_admin": false,
"username": "hhhhh"
}
]
Thông tin các Model
Review
var mongoose = require['mongoose'], Schema = mongoose.Schema
, ObjectId = Schema.ObjectId;
var ReviewSchema = new mongoose.Schema[{
user_id: { type: ObjectId, ref: 'User' },
book_id: { type: ObjectId },
star: { type: Number, default: 0 },
content: String
},
{
timestamps: true
}
];
Comment
var mongoose = require['mongoose'],
Schema = mongoose.Schema,
ObjectId = Schema.ObjectId;
var CommentSchema = new mongoose.Schema[{
user_id: { type: ObjectId, ref: 'User' },
review_id: { type: ObjectId, ref: 'Review' },
content: String
}];
Docs Home → MongoDB Manual
On this page
- Definition
- Syntax
- Equality Match with a Single Join Condition
- Join Conditions and Subqueries on a Joined Collection
- Correlated Subqueries Using Concise Syntax
- Behavior
- Views and Collation
- Restrictions
- Atlas Search Support
- Sharded Collections
- Slot-Based Query Execution Engine
- Examples
- Perform a Single Equality Join with
$lookup
- Use
$lookup
with an Array - Use
$lookup
with$mergeObjects
- Perform Multiple Joins and a Correlated Subquery with
$lookup
- Perform an Uncorrelated Subquery with
$lookup
- Perform a Concise Correlated Subquery with
$lookup
$lookup
Changed in version 5.1.
Performs a left outer join to a collection in the same database to filter in documents from the "joined" collection for processing. The
$lookup
stage adds a new array field to each input document. The new array field contains the matching documents from the "joined" collection. The $lookup
stage passes these reshaped documents to the
next stage.
Starting in MongoDB 5.1, $lookup
works across sharded collections.
To combine elements from two different collections, use the $unionWith
pipeline stage.
The $lookup
stage has the following syntaxes:
To perform an equality match between a field from the input documents with a field from the documents of the "joined" collection, the
$lookup
stage has this syntax:
{ $lookup: { from: , localField: , foreignField: , as: } }
The $lookup
takes a document with these fields:
from | Specifies the collection in the same database to perform the join with. Starting in MongoDB 5.1, the collection specified in the |
localField | Specifies the field from the documents input to the |
foreignField | Specifies the field from the documents in the |
as | Specifies the name of the new array field to add to the input documents. The new array field contains the matching documents from the |
The operation would correspond to the following pseudo-SQL statement:
SELECT *, FROM collection WHERE IN [ SELECT * FROM WHERE = ];
See these examples:
Perform a Single Equality Join with
$lookup
Use
$lookup
with an ArrayUse
$lookup
with$mergeObjects
MongoDB 3.6 adds support for:
Executing a pipeline on a joined collection.
Multiple join conditions.
Correlated and uncorrelated subqueries.
In MongoDB, a correlated subquery is a pipeline in a $lookup
stage that references document fields from a joined
collection. An uncorrelated subquery does not reference joined fields.
Note
Starting in MongoDB 5.0, for an uncorrelated subquery in a $lookup
pipeline stage containing a
$sample
stage, the $sampleRate
operator, or the $rand
operator, the subquery is always
run again if repeated. Previously, depending on the subquery output size, either the subquery output was cached or the subquery was run again.
MongoDB correlated subqueries are comparable to SQL correlated subqueries, where the inner query references outer query values. An SQL uncorrelated subquery does not reference outer query values.
MongoDB 5.0 also supports concise correlated subqueries.
To perform correlated and uncorrelated subqueries with two collections, and perform other join conditions besides a single equality match, use this
$lookup
syntax:
{ $lookup: { from: , let: { : , …, : }, pipeline: [ ], as: } }
The $lookup
stage accepts a document with these fields:
from | Specifies the collection in the same database to perform the join operation. Starting in MongoDB 5.1, the |
let | Optional. Specifies variables to use in the pipeline stages. Use the variable expressions to access the fields from the joined collection's documents that are input to the NoteTo reference variables in
pipeline stages, use the The let variables can be accessed by the stages in the
pipeline, including additional
|
pipeline
Specifies the pipeline
to run on the joined collection. The pipeline
determines the resulting documents from the joined collection. To return all documents, specify an empty pipeline
[]
.
The pipeline
cannot include the $out
stage or the
$merge
stage. Starting in v6.0, the pipeline
can contain the Atlas Search $search
stage as the first stage inside the pipeline. To learn more, see Atlas Search Support.
The pipeline
cannot directly access the joined document fields. Instead, define variables for the joined document fields using the
let option and then reference the variables in the pipeline
stages.
Note
To reference variables in pipeline stages, use the "$$"
syntax.
The
let variables can be accessed by the stages in the pipeline, including additional
$lookup
stages nested in the pipeline
.
A
$match
stage requires the use of an$expr
operator to access the variables. The$expr
operator allows the use of aggregation expressions inside of the$match
syntax.Starting in MongoDB 5.0, the
$eq
,$lt
,$lte
,$gt
, and$gte
comparison operators placed in an$expr
operator can use an index on thefrom
collection referenced in a$lookup
stage. Limitations:Multikey indexes are not used.
Indexes are not used for comparisons where the operand is an array or the operand type is undefined.
Indexes are not used for comparisons with more than one field path operand.
Other [non-
$match
] stages in the pipeline do not require an$expr
operator to access the variables.
as
Specifies the name of the new array field to add to the joined documents. The new array field contains the matching documents from the joined collection. If the specified name already exists in the joined document, the existing field is overwritten.