我正在关注 Brad Schiff 的 udemy 课程——从头开始学习 JavaScript 全栈,以及第 7-7 节。实时搜索功能,我在搜索帖子时遇到问题。安装axios后出现问题。 尝试使用课程中的确切代码,但仍然出现相同的错误:MongoError: FiledPath field names may not start with '$' 带有搜索功能的代码:
import axios from "axios";
import DOMPurify from "dompurify";
export default class search {
constructor() {
this.injectHTML();
this.headerSearchIcon = document.querySelector(".header-search-icon");
this.overlay = document.querySelector(".search-overlay");
this.closeIcon = document.querySelector(".close-live-search");
this.inputField = document.querySelector("#live-search-field");
this.resultsArea = document.querySelector(".live-search-results");
this.loaderIcon = document.querySelector(".circle-loader");
this.typingWaitTimer;
this.previousValue = "";
this.events();
events() {
this.inputField.addEventListener("keyup", () => this.keyPressHandler());
this.closeIcon.addEventListener("click", () => this.closeOverlay());
this.headerSearchIcon.addEventListener("click", (e) => {
e.preventDefault();
this.openOverlay();
});
}
keyPressHandler() {
let value = this.inputField.value;
if (value == "") {
clearTimeout(this.typingWaitTimer);
this.hideLoaderIcon();
this.hideResultsArea();
}
if (value != "" && value != this.previousValue) {
clearTimeout(this.typingWaitTimer);
this.showLoaderIcon();
this.hideResultsArea();
this.typingWaitTimer = setTimeout(() => this.sendRequest(), 750);
}
this.previousValue = value;
}
sendRequest() {
axios
.post("/search", { searchTerm: this.inputField.value })
.then((response) => {
console.log(response.data);
this.renderResultsHTML(response.data);
})
.catch(() => {
alert("Hello, the request failed.");
});
}
}
Post.js 文件中的其他代码
Post.reusablePostQuery = function (uniqueOperations, visitorId) {
return new Promise(async function (resolve, reject) {
let aggOperations = uniqueOperations.concat([
{
$lookup: {
from: "users",
localField: "author",
foreignField: "_id",
as: "authorDocument",
},
},
{
$project: {
title: 1,
body: 1,
createdDate: 1,
authorId: "$author",
author: { $arrayElemAt: ["$authorDocument", 0] },
},
},
]);
let posts = await postsCollection.aggregate(aggOperations).toArray();
// clean up author property in each post object
posts = posts.map(function (post) {
post.isVisitorOwner = post.authorId.equals(visitorId);
post.authorId = undefined;
post.author = {
username: post.author.username,
avatar: new User(post.author, true).avatar,
};
return post;
});
resolve(posts);
});
};
Post.findSingleById = function (id, visitorId) {
return new Promise(async function (resolve, reject) {
if (typeof id != "string" || !ObjectID.isValid(id)) {
reject();
return;
}
let posts = await Post.reusablePostQuery(
[{ $match: { _id: new ObjectID(id) } }],
visitorId
);
if (posts.length) {
console.log(posts[0]);
resolve(posts[0]);
} else {
reject();
}
});
};
Post.findByAuthorId = function (authorId) {
return Post.reusablePostQuery([
{ $match: { author: authorId } },
{ $sort: { createdDate: -1 } },
]);
};
Post.search = function (searchTerm) {
return new Promise(async (resolve, reject) => {
if (typeof searchTerm == "string") {
//this. added
let posts = await Post.reusablePostQuery([
{ $match: { $text: { $search: searchTerm } } },
{ $sort: { score: { $meta: "textScore" } } },
]);
resolve(posts);
} else {
reject();
}
});
};
postController.js 文件中的代码
exports.search = function (req, res) {
Post.search(req.body.searchTerm)
.then((posts) => {
res.json(posts);
})
.catch(() => {
res.json([]);
});
};