feat: add 'back/front end' in curriculum (#42596)
* chore: rename APIs and Microservices to include "Backend" (#42515) * fix typo * fix typo * undo change * Corrected grammar mistake Corrected a grammar mistake by removing a comma. * change APIs and Microservices cert title * update title * Change APIs and Microservices certi title * Update translations.json * update title * feat(curriculum): rename apis and microservices cert * rename folder structure * rename certificate * rename learn Markdown * apis-and-microservices -> back-end-development-and-apis * update backend meta * update i18n langs and cypress test Co-authored-by: Shaun Hamilton <shauhami020@gmail.com> * fix: add development to front-end libraries (#42512) * fix: added-the-word-Development-to-front-end-libraries * fix/added-the-word-Development-to-front-end-libraries * fix/added-word-development-to-front-end-libraries-in-other-related-files * fix/added-the-word-Development-to-front-end-and-all-related-files * fix/removed-typos-from-last-commit-in-index.md * fix/reverted-changes-that-i-made-to-dependecies * fix/removed xvfg * fix/reverted changes that i made to package.json * remove unwanted changes * front-end-development-libraries changes * rename backend certSlug and README * update i18n folder names and keys * test: add legacy path redirect tests This uses serve.json from the client-config repo, since we currently use that in production * fix: create public dir before moving serve.json * fix: add missing script * refactor: collect redirect tests * test: convert to cy.location for stricter tests * rename certificate folder to 00-certificates * change crowdin config to recognise new certificates location * allow translations to be used Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com> * add forwards slashes to path redirects * fix cypress path tests again * plese cypress * fix: test different challenge Okay so I literally have no idea why this one particular challenge fails in Cypress Firefox ONLY. Tom and I paired and spun a full build instance and confirmed in Firefox the page loads and redirects as expected. Changing to another bootstrap challenge passes Cypress firefox locally. Absolutely boggled by this. AAAAAAAAAAAAAAA * fix: separate the test Okay apparently the test does not work unless we separate it into a different `it` statement. >:( >:( >:( >:( Co-authored-by: Sujal Gupta <55016909+heysujal@users.noreply.github.com> Co-authored-by: Noor Fakhry <65724923+NoorFakhry@users.noreply.github.com> Co-authored-by: Oliver Eyton-Williams <ojeytonwilliams@gmail.com> Co-authored-by: Nicholas Carrigan (he/him) <nhcarrigan@gmail.com>
This commit is contained in:
@ -0,0 +1,76 @@
|
||||
---
|
||||
id: 587d7fb9367417b2b2512c12
|
||||
title: 通過鏈式調用輔助查詢函數來縮小搜索結果
|
||||
challengeType: 2
|
||||
forumTopicId: 301533
|
||||
dashedName: chain-search-query-helpers-to-narrow-search-results
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
如果不給 `Model.find()`(或者別的搜索方法)的最後一個參數傳入回調函數, 查詢將不會執行。 可以將查詢條件存儲在變量中供以後使用, 也可以通過鏈式調用這類變量來構建新的查詢字段。 實際的數據庫操作會在最後調用 `.exec()` 方法時執行。 必須把回調函數傳給最後一個方法。 Mongoose 提供了許多輔助查詢函數, 這裏使用最常見的一種。
|
||||
|
||||
# --instructions--
|
||||
|
||||
修改 `queryChain` 函數來查詢喜歡 `foodToSearch` 食物的人。 同時,需要將查詢結果按 `name` 屬性排序, 查詢結果應限制在兩個 document 內,並隱藏 age 屬性。 請鏈式調用 `.find()`、`.sort()`、`.limit()` 和 `.select()`,並在最後調用 `.exec()`, 並將 `done(err, data)` 回調函數傳入 `exec()`。
|
||||
|
||||
# --hints--
|
||||
|
||||
應該成功地鏈式調用輔助查詢函數。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.ajax({
|
||||
url: getUserInput('url') + '/_api/query-tools',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify([
|
||||
{ name: 'Pablo', age: 26, favoriteFoods: ['burrito', 'hot-dog'] },
|
||||
{ name: 'Bob', age: 23, favoriteFoods: ['pizza', 'nachos'] },
|
||||
{ name: 'Ashley', age: 32, favoriteFoods: ['steak', 'burrito'] },
|
||||
{ name: 'Mario', age: 51, favoriteFoods: ['burrito', 'prosciutto'] }
|
||||
])
|
||||
}).then(
|
||||
(data) => {
|
||||
assert.isArray(data, 'the response should be an Array');
|
||||
assert.equal(
|
||||
data.length,
|
||||
2,
|
||||
'the data array length is not what expected'
|
||||
);
|
||||
assert.notProperty(
|
||||
data[0],
|
||||
'age',
|
||||
'The returned first item has too many properties'
|
||||
);
|
||||
assert.equal(
|
||||
data[0].name,
|
||||
'Ashley',
|
||||
'The returned first item name is not what expected'
|
||||
);
|
||||
assert.notProperty(
|
||||
data[1],
|
||||
'age',
|
||||
'The returned second item has too many properties'
|
||||
);
|
||||
assert.equal(
|
||||
data[1].name,
|
||||
'Mario',
|
||||
'The returned second item name is not what expected'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,88 @@
|
||||
---
|
||||
id: 587d7fb6367417b2b2512c07
|
||||
title: 創建一個模型(Model)
|
||||
challengeType: 2
|
||||
forumTopicId: 301535
|
||||
dashedName: create-a-model
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
**C**RUD 第一小節——CREATE
|
||||
|
||||
首先,我們需要一個 Schema, 每一個 Schema 都對應一個 MongoDB 的 collection, 並且在相應的 collection 裏定義 documents 的“樣子”。 Schema 用於組成模型(Model), 我們甚至可以通過嵌套 Schema 來創建複雜的模型。目前我們先從簡。 我們可以根據模型創建實例,模型實例化後的對象稱爲 documents。
|
||||
|
||||
Replit 是一個真實的服務器,在其中,通過 handler 函數和數據庫交互。 這些函數會在特定事件(比如有人調用了我們的服務器 API)發生時執行。 接下來的挑戰題目即是以此爲基礎。 `done()` 是一個回調函數,它的作用是在一個異步操作(比如對數據庫進行插入、查詢、更新或刪除)執行完成時,通知我們可以繼續執行後續的其它代碼。 這與 Node.js 中的處理方式十分類似,在 Node.js 中,我們會在(異步操作)成功時調用 `done(null, data)`,在失敗時調用 `done(err)`。
|
||||
|
||||
注意:與遠程服務器進行交互時,我們需要考慮到發生錯誤的可能!
|
||||
|
||||
```js
|
||||
/* Example */
|
||||
|
||||
const someFunc = function(done) {
|
||||
//... do something (risky) ...
|
||||
if (error) return done(error);
|
||||
done(null, result);
|
||||
};
|
||||
```
|
||||
|
||||
# --instructions--
|
||||
|
||||
按下面的原型信息創建一個名爲 `personSchema` 的 schema:
|
||||
|
||||
```markup
|
||||
- Person Prototype -
|
||||
--------------------
|
||||
name : string [required]
|
||||
age : number
|
||||
favoriteFoods : array of strings (*)
|
||||
```
|
||||
|
||||
採用 Mongoose 基礎 schema 類型。 你如果還想添加更多的鍵,就請使用 required 或 unique 等簡單的驗證器(validators),並設置默認值。 詳情請參考 [Mongoose 文檔](http://mongoosejs.com/docs/guide.html)。
|
||||
|
||||
請從 `personSchema` 創建一個名爲 `Person` 的 model。
|
||||
|
||||
# --hints--
|
||||
|
||||
應當成功地通過 Mongoose schema 創建實例
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.post(getUserInput('url') + '/_api/mongoose-model', {
|
||||
name: 'Mike',
|
||||
age: 28,
|
||||
favoriteFoods: ['pizza', 'cheese']
|
||||
}).then(
|
||||
(data) => {
|
||||
assert.equal(data.name, 'Mike', '"model.name" is not what expected');
|
||||
assert.equal(data.age, '28', '"model.age" is not what expected');
|
||||
assert.isArray(
|
||||
data.favoriteFoods,
|
||||
'"model.favoriteFoods" is not an Array'
|
||||
);
|
||||
assert.include(
|
||||
data.favoriteFoods,
|
||||
'pizza',
|
||||
'"model.favoriteFoods" does not include the expected items'
|
||||
);
|
||||
assert.include(
|
||||
data.favoriteFoods,
|
||||
'cheese',
|
||||
'"model.favoriteFoods" does not include the expected items'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,56 @@
|
||||
---
|
||||
id: 587d7fb6367417b2b2512c09
|
||||
title: 創建並保存一條 Model 記錄
|
||||
challengeType: 2
|
||||
forumTopicId: 301536
|
||||
dashedName: create-and-save-a-record-of-a-model
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在這個挑戰中,你需要創建並保存一條模型數據。
|
||||
|
||||
# --instructions--
|
||||
|
||||
在 `createAndSavePerson` 函數中,用我們在上一個挑戰中寫好的 `Person` 構造函數創建 document 實例, 將包含 `name`、`age` 和 `favoriteFoods` 的對象傳給構造函數, 這些屬性的數據類型必須符合我們在 `personSchema` 中定義的類型。 然後在返回的 document 實例上調用方法 `document.save()`。 同時,按 Node.js 的方式爲它傳一個回調函數。 這是一種常見模式,以下所有CRUD方法都將這樣的回調函數作爲最後一個參數。
|
||||
|
||||
```js
|
||||
/* Example */
|
||||
|
||||
// ...
|
||||
person.save(function(err, data) {
|
||||
// ...do your stuff here...
|
||||
});
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
應成功地創建數據並保存一條數據到數據庫
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/_api/create-and-save-person').then(
|
||||
(data) => {
|
||||
assert.isString(data.name, '"item.name" should be a String');
|
||||
assert.isNumber(data.age, '28', '"item.age" should be a Number');
|
||||
assert.isArray(
|
||||
data.favoriteFoods,
|
||||
'"item.favoriteFoods" should be an Array'
|
||||
);
|
||||
assert.equal(data.__v, 0, 'The db item should be not previously edited');
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,68 @@
|
||||
---
|
||||
id: 587d7fb7367417b2b2512c0a
|
||||
title: 使用 model.create() 創建多條記錄
|
||||
challengeType: 2
|
||||
forumTopicId: 301537
|
||||
dashedName: create-many-records-with-model-create
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在一些情況下,比如進行數據庫初始化,你會需要創建很多 model 實例來用作初始數據。 `Model.create()` 接受一組像 `[{name: 'John', ...}, {...}, ...]` 的數組作爲第一個參數,並將其保存到數據庫。
|
||||
|
||||
# --instructions--
|
||||
|
||||
修改 `createManyPeople` 方法,使用 `arrayOfPeople` 作爲 `Model.create()` 的參數來創建多個 people 實例。
|
||||
|
||||
**注意:** 你可以使用在上一個挑戰中創建的 model 來完成當前挑戰。
|
||||
|
||||
# --hints--
|
||||
|
||||
應當成功地一次性創建多條數據
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.ajax({
|
||||
url: getUserInput('url') + '/_api/create-many-people',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify([
|
||||
{ name: 'John', age: 24, favoriteFoods: ['pizza', 'salad'] },
|
||||
{ name: 'Mary', age: 21, favoriteFoods: ['onions', 'chicken'] }
|
||||
])
|
||||
}).then(
|
||||
(data) => {
|
||||
assert.isArray(data, 'the response should be an array');
|
||||
assert.equal(
|
||||
data.length,
|
||||
2,
|
||||
'the response does not contain the expected number of items'
|
||||
);
|
||||
assert.equal(data[0].name, 'John', 'The first item is not correct');
|
||||
assert.equal(
|
||||
data[0].__v,
|
||||
0,
|
||||
'The first item should be not previously edited'
|
||||
);
|
||||
assert.equal(data[1].name, 'Mary', 'The second item is not correct');
|
||||
assert.equal(
|
||||
data[1].__v,
|
||||
0,
|
||||
'The second item should be not previously edited'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,57 @@
|
||||
---
|
||||
id: 587d7fb8367417b2b2512c11
|
||||
title: 使用 model.remove() 刪除多個 document
|
||||
challengeType: 2
|
||||
forumTopicId: 301538
|
||||
dashedName: delete-many-documents-with-model-remove
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
`Model.remove()` 可以用於刪除符合給定匹配條件的所有 document。
|
||||
|
||||
# --instructions--
|
||||
|
||||
修改 `removeManyPeople` 函數,使用 `nameToRemove` 刪除所有姓名是變量 `Model.remove()` 的人。 給它傳入一個帶有 `name` 字段的查詢 document 和一個回調函數。
|
||||
|
||||
**注意:** `Model.remove()` 不會返回被刪除的 document,而是會返回一個包含操作結果以及受影響的數據數量的 JSON 對象。 不要忘記將它傳入 `done()` 回調函數,因爲我們需要在挑戰的測試中調用它。
|
||||
|
||||
# --hints--
|
||||
|
||||
應一次性成功刪除多條數據
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.ajax({
|
||||
url: getUserInput('url') + '/_api/remove-many-people',
|
||||
type: 'POST',
|
||||
contentType: 'application/json',
|
||||
data: JSON.stringify([
|
||||
{ name: 'Mary', age: 16, favoriteFoods: ['lollipop'] },
|
||||
{ name: 'Mary', age: 21, favoriteFoods: ['steak'] }
|
||||
])
|
||||
}).then(
|
||||
(data) => {
|
||||
assert.isTrue(!!data.ok, 'The mongo stats are not what expected');
|
||||
assert.equal(
|
||||
data.n,
|
||||
2,
|
||||
'The number of items affected is not what expected'
|
||||
);
|
||||
assert.equal(data.count, 0, 'the db items count is not what expected');
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,53 @@
|
||||
---
|
||||
id: 587d7fb8367417b2b2512c10
|
||||
title: 使用 model.findByIdAndRemove 刪除一個 document
|
||||
challengeType: 2
|
||||
forumTopicId: 301539
|
||||
dashedName: delete-one-document-using-model-findbyidandremove
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
`findByIdAndRemove` 和 `findOneAndRemove` 類似於我們之前的更新方法, 它們將被刪除的 document 傳給數據庫。 和之前一樣,使用函數參數 `personId` 作爲查詢關鍵字。
|
||||
|
||||
# --instructions--
|
||||
|
||||
修改 `removeById` 函數,通過 `_id` 刪除一個人的數據, 可以使用 `findByIdAndRemove()` 或 `findOneAndRemove()` 方法。
|
||||
|
||||
# --hints--
|
||||
|
||||
應當成功地刪除一條數據
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.post(getUserInput('url') + '/_api/remove-one-person', {
|
||||
name: 'Jason Bourne',
|
||||
age: 36,
|
||||
favoriteFoods: ['apples']
|
||||
}).then(
|
||||
(data) => {
|
||||
assert.equal(data.name, 'Jason Bourne', 'item.name is not what expected');
|
||||
assert.equal(data.age, 36, 'item.age is not what expected');
|
||||
assert.deepEqual(
|
||||
data.favoriteFoods,
|
||||
['apples'],
|
||||
'item.favoriteFoods is not what expected'
|
||||
);
|
||||
assert.equal(data.__v, 0);
|
||||
assert.equal(data.count, 0, 'the db items count is not what expected');
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,85 @@
|
||||
---
|
||||
id: 587d7fb6367417b2b2512c06
|
||||
title: 安裝和設置 Mongoose
|
||||
challengeType: 2
|
||||
forumTopicId: 301540
|
||||
dashedName: install-and-set-up-mongoose
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
可以採用下面的任意一種方式完成這些挑戰:
|
||||
|
||||
- 克隆 [GitHub repo](https://github.com/freeCodeCamp/boilerplate-mongomongoose/) 並在本地完成項目。
|
||||
- 使用[我們的 Replit 上的初始化項目](https://replit.com/github/freeCodeCamp/boilerplate-mongomongoose)來完成項目。
|
||||
- 使用你選擇的網站生成器來完成項目, 並確保包含了我們 GitHub 倉庫的所有文件。
|
||||
|
||||
當完成本項目,請確認有一個正常運行的 demo 可以公開訪問。 然後將 URL 提交到 `Solution Link` 中。
|
||||
|
||||
在這個挑戰中,你將建立一個 MongoDB Atlas 數據庫並導入連接到它所需的軟件包。
|
||||
|
||||
按照<a href='https://www.freecodecamp.org/news/get-started-with-mongodb-atlas/' rel='noopener noreferrer' target='_blank'>這篇教程</a>在 MongoDB Atlas 創建一個託管數據庫。
|
||||
|
||||
# --instructions--
|
||||
|
||||
將 `mongodb` 和 `mongoose` 添加到項目的 `package.json` 文件中。 然後,在 `myApp.js` 文件中請求 `mongoose`。 創建一個 `.env` 文件,給它添加一個 `MONGO_URI` 變量。 變量的值爲你的 MongoDB Atlas 數據庫 URI。 應用單引號或雙引號包裹 URI。請記住,環境變量 `=` 兩邊不能有空格。 例如,`MONGO_URI='VALUE'`。 完成後,使用下面的代碼來連接數據庫。
|
||||
|
||||
```js
|
||||
mongoose.connect(<Your URI>, { useNewUrlParser: true, useUnifiedTopology: true });
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
“mongodb” 應在 package.json 中作爲依賴項定義。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/_api/file/package.json').then(
|
||||
(data) => {
|
||||
var packJson = JSON.parse(data);
|
||||
assert.property(packJson.dependencies, 'mongodb');
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
“mongoose” 應在 package.json 中作爲依賴項定義。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/_api/file/package.json').then(
|
||||
(data) => {
|
||||
var packJson = JSON.parse(data);
|
||||
assert.property(packJson.dependencies, 'mongoose');
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
應使用 “mongoose” 連接數據庫。
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/_api/is-mongoose-ok').then(
|
||||
(data) => {
|
||||
assert.isTrue(data.isMongooseOk, 'mongoose is not connected');
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,54 @@
|
||||
---
|
||||
id: 587d7fb8367417b2b2512c0e
|
||||
title: '通過執行查詢、編輯、保存來執行經典更新流程'
|
||||
challengeType: 2
|
||||
forumTopicId: 301541
|
||||
dashedName: perform-classic-updates-by-running-find-edit-then-save
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在過去,如果想要編輯 document 並以某種方式使用它(比如放到服務器的返回數據中),就必須執行查找、編輯和保存。 Mongoose 有一個專用的更新方法 `Model.update()`, 它與底層的 mongo 驅動綁定。 通過這個方法,我們可以批量編輯符合特定條件的多個 document。但問題在於,這個方法不會返回更新後的 document,而是返回狀態信息。 此外,它直接調用 mongo 的底層驅動,讓處理 model 的驗證變得更加棘手。
|
||||
|
||||
# --instructions--
|
||||
|
||||
在這個挑戰中,請使用參數 `personId` 作爲字段,修改 `findEditThenSave` 方法,以在數據庫中通過 `_id` 找到相應的 person(你可以使用之前挑戰中的任何一種方法)。 將 `"hamburger"` 添加到它的 `favoriteFoods` 清單中(你可以使用 `Array.push()`)。 然後,在查詢數據庫的方法的回調裏通過 `save()` 方法更新 `Person` 的數據。
|
||||
|
||||
**提示:** 如果你在 Schema 中將 `favoriteFoods` 聲明爲一個 Array(數組)並且沒有指定數組的類型(如 `[String]`), 那麼此時,`favoriteFoods` 就會是默認的 Mixed 類型。如果想編輯它,就必須執行 `document.markModified('edited-field')`。 詳情請參閱 [Mongoose 文檔](https://mongoosejs.com/docs/schematypes.html#Mixed)
|
||||
|
||||
# --hints--
|
||||
|
||||
應成功地對一條數據進行查找、編輯和更新
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.post(getUserInput('url') + '/_api/find-edit-save', {
|
||||
name: 'Poldo',
|
||||
age: 40,
|
||||
favoriteFoods: ['spaghetti']
|
||||
}).then(
|
||||
(data) => {
|
||||
assert.equal(data.name, 'Poldo', 'item.name is not what is expected');
|
||||
assert.equal(data.age, 40, 'item.age is not what expected');
|
||||
assert.deepEqual(
|
||||
data.favoriteFoods,
|
||||
['spaghetti', 'hamburger'],
|
||||
'item.favoriteFoods is not what expected'
|
||||
);
|
||||
assert.equal(data.__v, 1, 'The item should be previously edited');
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,58 @@
|
||||
---
|
||||
id: 587d7fb8367417b2b2512c0f
|
||||
title: 在 document 中執行新的更新方式——使用 model.findOneAndUpdate()
|
||||
challengeType: 2
|
||||
forumTopicId: 301542
|
||||
dashedName: perform-new-updates-on-a-document-using-model-findoneandupdate
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
最近發佈的 mongoose 版本簡化了 document 的更新方式, 但同時,一些高級功能(如 pre/post hook, 驗證)的使用方式也變得和以前不同。因此,在很多情景下,上一個挑戰中提到的老方法其實更常用。 新方法的加入,可以讓我們使用 `findByIdAndUpdate()` 來進行基於 id 的搜索。
|
||||
|
||||
# --instructions--
|
||||
|
||||
修改 `findAndUpdate` 函數,通過 `Name` 查詢人,並將查到的人的年齡設爲 `20` 歲, 將函數參數 `personName` 作爲查詢關鍵字。
|
||||
|
||||
**提示:** 你需要返回更新後的 document。 你可以把 `findOneAndUpdate()` 的第三個參數設置爲 `{ new: true }` 。 默認情況下,這個方法會返回修改前的數據。
|
||||
|
||||
# --hints--
|
||||
|
||||
應成功地使用 findOneAndUpdate 更新數據
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.post(getUserInput('url') + '/_api/find-one-update', {
|
||||
name: 'Dorian Gray',
|
||||
age: 35,
|
||||
favoriteFoods: ['unknown']
|
||||
}).then(
|
||||
(data) => {
|
||||
assert.equal(data.name, 'Dorian Gray', 'item.name is not what expected');
|
||||
assert.equal(data.age, 20, 'item.age is not what expected');
|
||||
assert.deepEqual(
|
||||
data.favoriteFoods,
|
||||
['unknown'],
|
||||
'item.favoriteFoods is not what expected'
|
||||
);
|
||||
assert.equal(
|
||||
data.__v,
|
||||
0,
|
||||
'findOneAndUpdate does not increment version by design!'
|
||||
);
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,53 @@
|
||||
---
|
||||
id: 587d7fb7367417b2b2512c0b
|
||||
title: 使用 model.find() 查詢數據庫
|
||||
challengeType: 2
|
||||
forumTopicId: 301543
|
||||
dashedName: use-model-find-to-search-your-database
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
我們嘗試一種最簡單的用法,`Model.find()` 接收一個查詢 document(一個 JSON 對象)作爲第一個參數,一個回調函數作爲第二個參數, 它會返回由匹配到的數據組成的數組。 這個方法支持很多搜索選項, 詳情請參閱文檔。
|
||||
|
||||
# --instructions--
|
||||
|
||||
修改 `findPeopleByName` 函數使用 <code>Model.find() -\> [Person]</code> 查詢所有給定名字的人。
|
||||
|
||||
請使用函數參數中的 `personName` 作爲搜索條件。
|
||||
|
||||
# --hints--
|
||||
|
||||
應成功地找到所有符合條件的數據
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.post(getUserInput('url') + '/_api/find-all-by-name', {
|
||||
name: 'r@nd0mN4m3',
|
||||
age: 24,
|
||||
favoriteFoods: ['pizza']
|
||||
}).then(
|
||||
(data) => {
|
||||
assert.isArray(data, 'the response should be an Array');
|
||||
assert.equal(
|
||||
data[0].name,
|
||||
'r@nd0mN4m3',
|
||||
'item.name is not what expected'
|
||||
);
|
||||
assert.equal(data[0].__v, 0, 'The item should be not previously edited');
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,48 @@
|
||||
---
|
||||
id: 587d7fb7367417b2b2512c0d
|
||||
title: 使用 model.findById() 方法,根據 _id 來搜索數據
|
||||
challengeType: 2
|
||||
forumTopicId: 301544
|
||||
dashedName: use-model-findbyid-to-search-your-database-by-id
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
在保存 document 的時候,MongoDB 會自動爲它添加 `_id` 字段,並給該字段設置一個唯一的僅包含數字和字母的值。 通過 `_id` 搜索是一個十分常見的操作,爲此,Mongoose 提供了一個專門的方法。
|
||||
|
||||
# --instructions--
|
||||
|
||||
修改 `findPersonById`,用 `Model.findById() -> Person` 來查詢唯一一個給定 `_id` 的人, 把函數參數 `personId` 作爲查詢鍵。
|
||||
|
||||
# --hints--
|
||||
|
||||
應成功地根據 Id 找到對應的數據
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.get(getUserInput('url') + '/_api/find-by-id').then(
|
||||
(data) => {
|
||||
assert.equal(data.name, 'test', 'item.name is not what expected');
|
||||
assert.equal(data.age, 0, 'item.age is not what expected');
|
||||
assert.deepEqual(
|
||||
data.favoriteFoods,
|
||||
['none'],
|
||||
'item.favoriteFoods is not what expected'
|
||||
);
|
||||
assert.equal(data.__v, 0, 'The item should be not previously edited');
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
@ -0,0 +1,51 @@
|
||||
---
|
||||
id: 587d7fb7367417b2b2512c0c
|
||||
title: 使用 model.findOne() 從數據庫中返回一個單一匹配的 Document
|
||||
challengeType: 2
|
||||
forumTopicId: 301545
|
||||
dashedName: use-model-findone-to-return-a-single-matching-document-from-your-database
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
`Model.findOne()` 與 `Model.find()` 十分類似,但就算數據庫中有很多條數據可以匹配查詢條件,它也只返回一個 document,而不會返回一個數組, 如果查詢條件是聲明爲唯一值的屬性,它會更加適用。
|
||||
|
||||
# --instructions--
|
||||
|
||||
修改 `findOneByFood` 函數,用 `Model.findOne() -> Person` 來查詢在收藏夾中有某種食物的一個人。 將函數參數中的 `food` 作爲檢索條件。
|
||||
|
||||
# --hints--
|
||||
|
||||
應成功地找到一個數據
|
||||
|
||||
```js
|
||||
(getUserInput) =>
|
||||
$.post(getUserInput('url') + '/_api/find-one-by-food', {
|
||||
name: 'Gary',
|
||||
age: 46,
|
||||
favoriteFoods: ['chicken salad']
|
||||
}).then(
|
||||
(data) => {
|
||||
assert.equal(data.name, 'Gary', 'item.name is not what expected');
|
||||
assert.deepEqual(
|
||||
data.favoriteFoods,
|
||||
['chicken salad'],
|
||||
'item.favoriteFoods is not what expected'
|
||||
);
|
||||
assert.equal(data.__v, 0, 'The item should be not previously edited');
|
||||
},
|
||||
(xhr) => {
|
||||
throw new Error(xhr.responseText);
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```js
|
||||
/**
|
||||
Backend challenges don't need solutions,
|
||||
because they would need to be tested against a full working project.
|
||||
Please check our contributing guidelines to learn more.
|
||||
*/
|
||||
```
|
Reference in New Issue
Block a user