我正在尝试使用 nodejs 和 MongoDB 制作一个搜索 api。我试图用谷歌搜索这个问题,我确实在那里找到了一些东西,但在尝试实现时,我收到一条错误消息。老实说,我不知道如何解决这个问题,我对制作搜索API一无所知。所以任何帮助或建议都会对我有帮助。
这是我在 google 上找到的帖子的链接 Building a simple search api.
错误
{
"error": {
"message": "Cast to ObjectId failed for value \"search\" at path \"_id\" for model \"Post\"",
"name": "CastError",
"stringValue": "\"search\"",
"kind": "ObjectId",
"value": "search",
"path": "_id"
}
}
这是我的代码
postController.search = (req, res) => {
var response = [];
if(typeof req.query.title !== 'undefined'){
db.Post.filter(function(post) {
if(post.title === req.query.title){
console.log(req.body);
response.push(post);
console.log(post);
}
});
}
response = _.uniqBy(response, '_id');
if(Object.key(req.query).length === 0){
response = db.Post
}
res.json(response);
};
集合中的数据
"data": [
{
"isDeleted": false,
"_comments": [],
"_id": "5d39122036117d2ea81b434c",
"title": "facebook post",
"link": "facebook.com",
"_creator": {
"createdAt": "2019-07-25T01:42:21.252Z",
"username": "adityakmr"
},
"createdAt": "2019-07-25T02:21:20.634Z",
"__v": 0
},
]
如果您尝试创建一个 API 来根据标题搜索 mongoDB 集合,即;文本字段尝试实现 mongoDB 的文本搜索功能:mongoDB 中的文本搜索 ,只需在标题字段上创建一个文本索引,然后使用 post 方法创建一个 API,该方法接收可针对标题字段进行查询的参数。
文本搜索可能有点棘手,它可以帮助您进行模糊/部分/全文搜索 - 使用正则表达式也非常有益。
查看 Node.js API 示例的链接:
首先,您需要使用
async/await
来模块化您的代码。我建议不要将整个代码写在 controller.js
文件中,API 可以按照以下方式制作(路由 - 控制器 - utils )。
postRoutes.js
postRouter.get('/search-post', postCtr.searchPost);
postController.js
const postUtils = require('./postUtils');
const postController = {};
postController.searchPost = async (req, res) => {
try {
const { title } = req.query;
const result = await postUtils.searchPost(title);
return res.status(200).json(result);
} catch (err) {
return res.status(err.code).json({ error: err.error });
}
};
module.exports = postController;
postUtils.js
const Post = require('./postModel');
const postUtils = {};
postUtils.searchPost = async (title) => {
try {
let result = [];
if(title){
// Even you can perform regex in your search
result = await Post.find({ title: title });
}
return result;
} catch (err) {
const errorObj = { code: 500, error: 'Internal server error' }; // It can be dynamic
throw errorObj;
}
};
module.exports = postUtils;
postModel.js
const mongoose = require('mongoose');
const postSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: 'user',
required: true,
},
// Your fields ...
}, { collection: 'post', timestamps: true });
const post = mongoose.model('post', postSchema);
module.exports = post;
使用这种结构,您可以轻松调试代码,并且它也易于管理。
在您上面指定的链接中,他们使用存储在名为
store.js
的文件中的对象数组,但不是 mongoDB。所以他们直接使用Array.filter
方法进行过滤。
但是在使用 mongoose(对象建模工具)的 mongoDB 中,您可以使用
collection.find()
方法。
所以您的问题的解决方案如下
postController.search = async (req, res) => {
var response = [];
if (req.query.title) {
response = await db.Post.find({title: req.query.title});
}
res.json(response);
};
find 是内置的查询方法,有助于查询集合,您可以传递多个属性进行查询。