Skip to content

Commit d844c64

Browse files
author
Dave Cuthbert
authored
DOCSP-25167 BACKPORT (#1869)
* DOCSP-25167 BACKPORT * TOC link
1 parent f4c9d1c commit d844c64

File tree

2 files changed

+132
-0
lines changed

2 files changed

+132
-0
lines changed

source/core/databases-and-collections.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,4 +133,5 @@ or the :method:`db.getCollectionInfos()` method.
133133

134134
/core/views
135135
/core/materialized-views
136+
/core/views/join-collections-with-view
136137
/core/capped-collections
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
.. _manual-views-lookup:
2+
3+
==================================
4+
Use a View to Join Two Collections
5+
==================================
6+
7+
.. default-domain:: mongodb
8+
9+
.. contents:: On this page
10+
:local:
11+
:backlinks: none
12+
:depth: 2
13+
:class: singlecol
14+
15+
You can use :pipeline:`$lookup` to create a view over two collections
16+
and then run queries against the view. Applications can query the view
17+
without having to construct or maintain complex pipelines.
18+
19+
Example
20+
-------
21+
22+
Create two sample collections, ``inventory`` and ``orders``:
23+
24+
.. code-block:: javascript
25+
26+
db.inventory.insertMany( [
27+
{ prodId: 100, price: 20, quantity: 125 },
28+
{ prodId: 101, price: 10, quantity: 234 },
29+
{ prodId: 102, price: 15, quantity: 432 },
30+
{ prodId: 103, price: 17, quantity: 320 }
31+
] )
32+
33+
db.orders.insertMany( [
34+
{ orderId: 201, custid: 301, prodId: 100, numPurchased: 20 },
35+
{ orderId: 202, custid: 302, prodId: 101, numPurchased: 10 },
36+
{ orderId: 203, custid: 303, prodId: 102, numPurchased: 5 },
37+
{ orderId: 204, custid: 303, prodId: 103, numPurchased: 15 },
38+
{ orderId: 205, custid: 303, prodId: 103, numPurchased: 20 },
39+
{ orderId: 206, custid: 302, prodId: 102, numPurchased: 1 },
40+
{ orderId: 207, custid: 302, prodId: 101, numPurchased: 5 },
41+
{ orderId: 208, custid: 301, prodId: 100, numPurchased: 10 },
42+
{ orderId: 209, custid: 303, prodId: 103, numPurchased: 30 }
43+
] )
44+
45+
Create a Joined View
46+
~~~~~~~~~~~~~~~~~~~~
47+
48+
This command uses :method:`db.createView()` to create a new view named
49+
``sales`` based on the ``orders`` collection:
50+
51+
.. code-block:: javascript
52+
53+
db.createView( "sales", "orders", [
54+
{
55+
$lookup:
56+
{
57+
from: "inventory",
58+
localField: "prodId",
59+
foreignField: "prodId",
60+
as: "inventoryDocs"
61+
}
62+
},
63+
{
64+
$project:
65+
{
66+
_id: 0,
67+
prodId: 1,
68+
orderId: 1,
69+
numPurchased: 1,
70+
price: "$inventoryDocs.price"
71+
}
72+
},
73+
{ $unwind: "$price" }
74+
] )
75+
76+
In the example:
77+
78+
- The :pipeline:`$lookup` stage uses the ``prodId`` field in the
79+
``orders`` collection to "join" documents in the ``inventory``
80+
collection that have matching ``prodId`` fields.
81+
- The matching documents are added as an array in the ``inventoryDocs``
82+
field.
83+
- The :pipeline:`$project` stage selects a subset of the available
84+
fields.
85+
- The :pipeline:`$unwind` stage converts the ``price`` field from an
86+
array to a scalar value.
87+
88+
The documents in the ``sales`` view are:
89+
90+
.. code-block:: javascript
91+
:copyable: false
92+
93+
{ orderId: 201, prodId: 100, numPurchased: 20, price: 20 },
94+
{ orderId: 202, prodId: 101, numPurchased: 10, price: 10 },
95+
{ orderId: 203, prodId: 102, numPurchased: 5, price: 15 },
96+
{ orderId: 204, prodId: 103, numPurchased: 15, price: 17 },
97+
{ orderId: 205, prodId: 103, numPurchased: 20, price: 17 },
98+
{ orderId: 206, prodId: 102, numPurchased: 1, price: 15 },
99+
{ orderId: 207, prodId: 101, numPurchased: 5, price: 10 },
100+
{ orderId: 208, prodId: 100, numPurchased: 10, price: 20 },
101+
{ orderId: 209, prodId: 103, numPurchased: 30, price: 17 }
102+
103+
Query the View
104+
~~~~~~~~~~~~~~
105+
106+
To find the total amount sold of each product, query the view:
107+
108+
.. code-block:: javascript
109+
110+
db.sales.aggregate( [
111+
{
112+
$group:
113+
{
114+
_id: "$prodId",
115+
amountSold: { $sum: { $multiply: [ "$price", "$numPurchased" ] } }
116+
}
117+
}
118+
] )
119+
120+
The output is:
121+
122+
.. code-block:: javascript
123+
:copyable: false
124+
125+
[
126+
{ _id: 102, amountSold: 90 },
127+
{ _id: 101, amountSold: 150 },
128+
{ _id: 103, amountSold: 1105 },
129+
{ _id: 100, amountSold: 600 }
130+
]
131+

0 commit comments

Comments
 (0)