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:
Shaun Hamilton
2021-08-14 03:57:13 +01:00
committed by GitHub
parent 4df2a0c542
commit c2a11ad00d
1215 changed files with 790 additions and 449 deletions

View File

@ -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.
*/
```

View File

@ -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.
*/
```

View File

@ -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.
*/
```

View File

@ -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.
*/
```

View File

@ -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.
*/
```

View File

@ -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.
*/
```

View File

@ -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.
*/
```

View File

@ -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.
*/
```

View File

@ -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.
*/
```

View File

@ -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.
*/
```

View File

@ -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.
*/
```

View File

@ -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.
*/
```