What is a view

Similar to traditional relational databases, MongoDB also has the concept of a view, or what we call a view.

MongoDB’s View is a queryable object whose content is actually provided by an aggregation pipeline defined on other Views and collections. In other words, the original data of view is based on other views or collections. The data source is still collection, and the original data is processed by aggregation pipeline to produce the final actual data.

Based on the above principle, the view of the data is actually a virtual, not on the disk persistent but a temporary stay in memory, database restart the view data will be cleared, but because of the raw data is persistence, so the reliability of data need not worry, the query again triggered when polymerization pipeline real-time computation and kept in memory again

When we query a view, the view does not initially have the data we want, resulting in aggregated pipeline calculations on demand

Since the view’s raw data depends on other collections or views, and it does not store its data and related data structures independently, the view is read-only and cannot be written to

A MongoDB view is a queryable object whose contents are defined by an aggregation pipeline on other collections or views.

MongoDB does not persist the view contents to disk.

A view’s content is computed on-demand when a client queries the view.

MongoDB can require clients to have permission to query the view. MongoDB does not support write operations against views.

use

  • Data security and sensitive data protection

Create a view on a collection of employee data to exclude any private or personal information (PII). Applications can query the view for employee data that does not contain any PII.

  • Processing and extraction of raw data

Create a view on a collection of collected sensor data to add computed fields and metrics. Applications can use simple find operations to query the data.

  • Combine multiple collections into one view to simplify the associated query among complex multiple collections

Create a view that joins two collections containing inventory and order history respectively. Applications can query the joined data without managing or understanding the underlying complex pipeline.

The working principle of

When a client queries a view,MongoDB appends the query statement to the aggregate pipe that defines the view, forming a combined aggregate pipe, and MongoDB then executes the combined aggregate pipe and optimizes the pipeline in the process

When clients query a view, MongoDB appends the client query to the underlying pipeline and returns the results of that combined pipeline to the client. MongoDB may apply aggregation pipeline optimizations to the combined pipeline.

Quick learning

We first design a scenario: a person has salary and monthly expenses, and the expenses have specific bills. We need to query the details of the person’s net income and expenses in a certain month. Passwords are sensitive data and cannot be queried directly.

The original data

The user information

Db. User. InsertMany ([{" username ":" Thinktik ", "password" : "dqw3er23", "salary" : 10000, "expense", 4534.23}. {" username ":" Andy ", "password" : "htyrt", "salary" : 25000, "expense", 14534.23}. {"username":"Sandy","password":"grtyr","salary":5000,"expense":7978}, {" username ":" Tom "and" password ":" tyhrt ", "salary" : 13000, "expense", 3534.89}. {" username ":" Jack ", "password" : "jtyr", "salary" : 230000, "expense" : 7534.43}])Copy the code

The billing information

Db. Bills. InsertMany ([{" customer ":" Thinktik ", "details" : {" watch ", 4534.23}}, {" customer ":" Andy ", "details" : {" motorcycle ", 14534.23}}, {" customer ":" Sandy ", "details" : {" phone ": 7978}}, {" customer ":" Tom "and" details ": {" bicycle", 3534.89}}, {" customer ":" Jack ", "details" : {" PC ", 7534.43}},])Copy the code

Use views to hide sensitive data

Create a view

db.createCollection(
  "v_user",
  {
    "viewOn" : "user",
    "pipeline" : [
        {$project:{"password":0}}
    ]
  }
)
Copy the code

The query

We found that the password information was blocked

think_db> db.createCollection( ... "v_user", ... {... "viewOn" : "user", ..... "pipeline" : [ ..... {$project:{"password":0}} ..... ] . }...). { ok: 1 } think_db> db.v_user.find({}) [ { _id: ObjectId("61ce05630065f8ac6bef457f"), username: 'Thinktik', salary: 10000, expense: 4534.23}, {_id: ObjectId(" 61CE05630065f8AC6bef4580 "), username: 'Andy', salary: 25000, expense: 14534.23}, {_id: ObjectId(" 61CE05630065f8AC6bef4581 "), username: 'Sandy', salary: 5000, expense: 7978}, {_id: ObjectId(" 61CE05630065f8AC6bef4581 "), username: 'Sandy', salary: 5000, expense: 7978} ObjectId(" 61CE05630065f8AC6BEF4582 "), username: 'Tom', salary: 13000, expense: 3534.89}, {_id: ObjectId(" 61CE05630065f8AC6BEF4583 "), username: 'Jack', salary: 230000, expense: 7534.43}]Copy the code

Process raw data with views

Calculate the net income for the month

think_db> db.v_user.drop() true think_db> db.createCollection( ... "v_user", ... {... "viewOn" : "user", ..... "pipeline" : [ ..... {$project:{"password":0}}, ..... {$addFields:{"profit":{ $subtract: [ "$salary", "$expense" ] }}} ..... ] . }...). { ok: 1 } think_db>Copy the code

The query

We see that we have successfully processed the raw data and added a field to represent the net income

think_db> db.v_user.find({}) [ { _id: ObjectId("61ce05630065f8ac6bef457f"), username: 'Thinktik', salary: 10000, expense: 4534.23, profit: 5465.77}, {_id: ObjectId(" 61CE05630065f8AC6bef4580 "), username: 'Andy', salary: 25000, expense: 14534.23, profit: 10465.77}, {_id: ObjectId(" 61CE05630065f8AC6bef4581 "), username: 'Sandy', salary: 5000, expense: 7978, profit: -2978 }, { _id: ObjectId("61ce05630065f8ac6bef4582"), username: 'Tom', salary: 13000, expense: 3534.89, profit: 9465.11}, {_id: ObjectId(" 61CE05630065f8AC6bef4583 "), username: 'Jack', salary: 230000, expense: 7534.43, profit: 222465.57}]Copy the code

Combine multiple collections using views

Combine user and Bill

think_db> db.v_user.drop() true think_db> db.createCollection( ... "v_user", ... {... "viewOn" : "user", ..... "pipeline" : [ ..... {$project:{"password":0}}, ..... {$addFields:{"profit":{ $subtract: [ "$salary", "$expense" ] }}}, ..... {$lookup: ....... { ......... from: "bills", ......... localField: "username", ......... foreignField: "customer", ......... as: "details" ......... } ....... }, ..... ] . }...). { ok: 1 } think_db>Copy the code

The query

We can see that we have successfully glued user and Bill together, making it very easy to implement associative queries

think_db> db.v_user.find({}) [ { _id: ObjectId("61ce05630065f8ac6bef457f"), username: 'Thinktik', salary: 10000, expense: 4534.23, profit: 5465.77, details: [{_id: ObjectId(" 61ce0a550065f8AC6bef4584 "), customer: 'Thinktik', details: {watch: 4534.23}}, {_id: ObjectId(" 61CE0B8D0065F8AC6BEF4589 "), Customer: 'Thinktik', details: {watch: 4534.23}}, {_id: ObjectId(" 61CE0B8D0065f8AC6BEF4589 "), Customer: {watch: 4534.23}}]}, {_id: ObjectId(" 61CE05630065f8AC6bef4580 "), username: 'Andy', salary: 25000, expense: 14534.23, profit: 10465.77, details: [{_id: ObjectId(" 61CE0A550065f8AC6BEF4585 "), Customer: 'Andy', details: {motorcycle: 14534.23}}, {_id: ObjectId(" 61CE0B8D0065F8AC6BEF458A "), Customer: 'Andy', details: {motorcycle: 14534.23}}, {_id: ObjectId(" 61CE0B8D0065f8AC6BEf458A "), Customer: 'Andy', details: {motorcycle: 14534.23}}]}, {_id: ObjectId(" 61CE05630065f8AC6bef4581 "), username: 'Sandy', salary: 5000, expense: 7978, profit: -2978, details: [ { _id: ObjectId("61ce0a550065f8ac6bef4586"), customer: 'Sandy', details: { phone: 7978 } }, { _id: ObjectId("61ce0b8d0065f8ac6bef458b"), customer: 'Sandy', details: { phone: 7978 } } ] }, { _id: ObjectId(" 61CE05630065f8AC6BEF4582 "), username: 'Tom', Salary: 13000, expense: 3534.89, profit: 9465.11, details: [{_id: ObjectId(" 61CE0A550065f8AC6BEF4587 "), Customer: 'Tom', details: {bicycle: 3534.89}}, {_id: ObjectId(" 61CE0a550065f8AC6BEF4587 ") ObjectId(" 61CE0B8D0065F8AC6BEF458C "), Customer: 'Tom', details: {bicycle: 3534.89}}]}, {_id: ObjectId(" 61CE05630065f8AC6BEF4583 "), username: 'Jack', Salary: 230000, expense: 7534.43, profit: 222465.57, details: [{_id: ObjectId(" 61CE0A550065f8AC6BEF4588 "), Customer: 'Jack', details: {PC: 7534.43}}, {_id: ObjectId(" 61CE0B8D0065F8AC6BEF458D "), Customer: 'Jack', details: {PC: 7534.43}}]}]Copy the code

Conclusion:

  • The view itself does not own raw data; its own data is based on other views or collections
  • The view uses the aggregate pipe to process the raw data and generate its own temporary data, which is cached in memory and triggers on-demand calculation of the aggregate pipe when the desired data is not present