部分时间对社交媒体类型网络应用程序的搜索实现
Search implementation to social media type web app working part of the time
我正在尝试制作一个社交媒体类型的应用程序,目前正在尝试实现一个搜索功能以便能够找到朋友。我有下面的代码,它有时工作而其他时候不工作(真的很令人沮丧!)我很确定这与 javascript 的异步性质有关。我想我可以通过将第二个 find 放在 then 函数中来解决这个问题。代码应该搜索以检查用户的名字,然后搜索用户的姓氏并将其推送到一个名为 users 的数组中,然后将其展平并编辑为仅具有唯一的用户对象。然后将其传递给显示用户的车把。问题似乎来自以下测试,这些测试处理多个单词,有时搜索第二个单词,有时不搜索:
- 用户搜索 returns 每个词的结果
- 搜索不受添加非字母数字字符的影响
控制器
const User = require("../models/user");
const SearchController = {
Index: (req, res) => {
const users = [];
User.find().then((user) => {
users.push(user);
const merged = [].concat.apply([], users);
const uniqueArray = merged.filter((value, index) => {
const _value = JSON.stringify(value);
return (
index ===
merged.findIndex((obj) => {
return JSON.stringify(obj) === _value;
})
);
});
res.render("search/index", { users: uniqueArray });
});
},
Create: (req, res) => {
const searchArray = req.body.message.replace(/[\W_]+/g, " ").split(/[ ,]+/);
const users = [];
searchArray.forEach((name) => {
User.find({
firstName: { $regex: name, $options: "i" },
// lastName: { $regex: name, $options: "i" },
}).then((user) => {
users.push(user);
User.find({
// firstName: { $regex: name, $options: "i" },
lastName: { $regex: name, $options: "i" },
}).then((user) => {
users.push(user);
const merged = [].concat.apply([], users);
const uniqueArray = merged.filter((value, index) => {
const _value = JSON.stringify(value);
return (
index ===
merged.findIndex((obj) => {
return JSON.stringify(obj) === _value;
})
);
});
res.render("search/index", { users: uniqueArray });
});
});
});
},
};
module.exports = SearchController;
赛普拉斯测试
describe("Searching users", () => {
beforeEach(() => {
cy.signUp();
cy.signUp("Chris", "Coding", "chris@coding.com", "12345");
cy.signUp("Paul", "Coding", "paul@coding.com", "12345");
cy.signUp("Adam", "Woodcock", "adam@woodcock.com", "12345");
cy.signUp("Kathleen", "Woodcock", "kathleen@woodcock.com", "12345");
cy.signUp("George", "Hett", "george@hett.com", "12345");
cy.signUp("Rob", "Oman", "rob@oman.com", "12345");
});
it("A user can search for other users", () => {
cy.login();
cy.get("#searchBox").type("george");
cy.get("#searchButton").click();
cy.get(".user-container").first().should("contain", "George Hett");
});
it("A user can search for other users by last name", () => {
cy.login();
cy.get("#searchBox").type("woodcock");
cy.get("#searchButton").click();
cy.get(".user-container").should("have.length", 2);
cy.get(".user-container").should("contain", "Adam Woodcock");
cy.get(".user-container").should("contain", "Kathleen Woodcock");
});
it("A blank search returns all users", () => {
cy.login();
cy.get("#searchButton").click();
cy.get(".user-container").should("have.length", 7);
cy.get(".user-container").should("contain", "Adam Woodcock");
cy.get(".user-container").should("contain", "Kathleen Woodcock");
cy.get(".user-container").should("contain", "Chris Coding");
cy.get(".user-container").should("contain", "Paul Coding");
cy.get(".user-container").should("contain", "Rob Oman");
cy.get(".user-container").should("contain", "George Hett");
cy.get(".user-container").should("contain", "Barry Barry-Barroldsson");
});
it("Visiting the search page without going through the search bar returns all users", () => {
cy.login();
cy.visit("/search");
cy.get(".user-container").should("have.length", 7);
cy.get(".user-container").should("contain", "Adam Woodcock");
cy.get(".user-container").should("contain", "Kathleen Woodcock");
cy.get(".user-container").should("contain", "Chris Coding");
cy.get(".user-container").should("contain", "Paul Coding");
cy.get(".user-container").should("contain", "Rob Oman");
cy.get(".user-container").should("contain", "George Hett");
cy.get(".user-container").should("contain", "Barry Barry-Barroldsson");
});
it("A search is not affected by adding non alphanumeric characters", () => {
cy.login();
cy.get("#searchBox").type("Chris /.,[] Coding");
cy.get("#searchButton").click();
cy.get(".user-container").should("have.length", 2);
cy.get(".user-container").should("contain", "Chris Coding");
cy.get(".user-container").should("contain", "Paul Coding");
});
it("A user's search returns results for each word", () => {
cy.login();
cy.get("#searchBox").type("Chris Woodcock");
cy.get("#searchButton").click();
cy.get(".user-container").should("have.length", 3);
cy.get(".user-container").should("contain", "Adam Woodcock");
cy.get(".user-container").should("contain", "Kathleen Woodcock");
cy.get(".user-container").should("contain", "Chris Coding");
});
});
请您推荐我可以进行哪些调整以使此代码正常运行
你可能会发现这个效果更好,虽然我找不到任何容易因异步处理而失败的东西。
我假设 User.find()
returns 一个承诺。
const promises = searchArray.map((name) => {
return User.find({
firstName: { $regex: name, $options: "i" },
lastName: { $regex: name, $options: "i" },
})
})
Promise.all(promises).then((values) => {
const uniqueArray = values
.flat()
.filter((value, index, arr) => arr.indexOf(value) === index)
res.render("search/index", { users: uniqueArray });
})
cy.get(".user-container").should("have.length", 3);
应该处理测试结束时的任何滞后,但如果执行 multi-level 搜索可能需要超过 4 秒,您可能希望增加超时。
cy.get(".user-container", {timeout:10000})
.should("have.length", 3);
我通过将上面的内容重构为这个,通过更改 for each 循环来构建最终查询并将其传递给 find 语句,然后渲染效果非常好,从而设法解决了我自己的问题。我还重构了索引路由。
const User = require("../models/user");
const SearchController = {
Index: (req, res) => {
User.find().then((users) => {
res.render("search/index", { users: users });
});
},
Create: (req, res) => {
const searchArray = req.body.message.replace(/[\W_]+/g, " ").split(/[ ,]+/);
const findQuery = [];
searchArray.forEach((name) => {
const first = { firstName: { $regex: name, $options: "i" } };
const second = { lastName: { $regex: name, $options: "i" } };
findQuery.push(first, second);
});
User.find({ $or: findQuery }).then((users) => {
res.render("search/index", { users: users });
});
},
};
module.exports = SearchController;
我正在尝试制作一个社交媒体类型的应用程序,目前正在尝试实现一个搜索功能以便能够找到朋友。我有下面的代码,它有时工作而其他时候不工作(真的很令人沮丧!)我很确定这与 javascript 的异步性质有关。我想我可以通过将第二个 find 放在 then 函数中来解决这个问题。代码应该搜索以检查用户的名字,然后搜索用户的姓氏并将其推送到一个名为 users 的数组中,然后将其展平并编辑为仅具有唯一的用户对象。然后将其传递给显示用户的车把。问题似乎来自以下测试,这些测试处理多个单词,有时搜索第二个单词,有时不搜索:
- 用户搜索 returns 每个词的结果
- 搜索不受添加非字母数字字符的影响
控制器
const User = require("../models/user");
const SearchController = {
Index: (req, res) => {
const users = [];
User.find().then((user) => {
users.push(user);
const merged = [].concat.apply([], users);
const uniqueArray = merged.filter((value, index) => {
const _value = JSON.stringify(value);
return (
index ===
merged.findIndex((obj) => {
return JSON.stringify(obj) === _value;
})
);
});
res.render("search/index", { users: uniqueArray });
});
},
Create: (req, res) => {
const searchArray = req.body.message.replace(/[\W_]+/g, " ").split(/[ ,]+/);
const users = [];
searchArray.forEach((name) => {
User.find({
firstName: { $regex: name, $options: "i" },
// lastName: { $regex: name, $options: "i" },
}).then((user) => {
users.push(user);
User.find({
// firstName: { $regex: name, $options: "i" },
lastName: { $regex: name, $options: "i" },
}).then((user) => {
users.push(user);
const merged = [].concat.apply([], users);
const uniqueArray = merged.filter((value, index) => {
const _value = JSON.stringify(value);
return (
index ===
merged.findIndex((obj) => {
return JSON.stringify(obj) === _value;
})
);
});
res.render("search/index", { users: uniqueArray });
});
});
});
},
};
module.exports = SearchController;
赛普拉斯测试
describe("Searching users", () => {
beforeEach(() => {
cy.signUp();
cy.signUp("Chris", "Coding", "chris@coding.com", "12345");
cy.signUp("Paul", "Coding", "paul@coding.com", "12345");
cy.signUp("Adam", "Woodcock", "adam@woodcock.com", "12345");
cy.signUp("Kathleen", "Woodcock", "kathleen@woodcock.com", "12345");
cy.signUp("George", "Hett", "george@hett.com", "12345");
cy.signUp("Rob", "Oman", "rob@oman.com", "12345");
});
it("A user can search for other users", () => {
cy.login();
cy.get("#searchBox").type("george");
cy.get("#searchButton").click();
cy.get(".user-container").first().should("contain", "George Hett");
});
it("A user can search for other users by last name", () => {
cy.login();
cy.get("#searchBox").type("woodcock");
cy.get("#searchButton").click();
cy.get(".user-container").should("have.length", 2);
cy.get(".user-container").should("contain", "Adam Woodcock");
cy.get(".user-container").should("contain", "Kathleen Woodcock");
});
it("A blank search returns all users", () => {
cy.login();
cy.get("#searchButton").click();
cy.get(".user-container").should("have.length", 7);
cy.get(".user-container").should("contain", "Adam Woodcock");
cy.get(".user-container").should("contain", "Kathleen Woodcock");
cy.get(".user-container").should("contain", "Chris Coding");
cy.get(".user-container").should("contain", "Paul Coding");
cy.get(".user-container").should("contain", "Rob Oman");
cy.get(".user-container").should("contain", "George Hett");
cy.get(".user-container").should("contain", "Barry Barry-Barroldsson");
});
it("Visiting the search page without going through the search bar returns all users", () => {
cy.login();
cy.visit("/search");
cy.get(".user-container").should("have.length", 7);
cy.get(".user-container").should("contain", "Adam Woodcock");
cy.get(".user-container").should("contain", "Kathleen Woodcock");
cy.get(".user-container").should("contain", "Chris Coding");
cy.get(".user-container").should("contain", "Paul Coding");
cy.get(".user-container").should("contain", "Rob Oman");
cy.get(".user-container").should("contain", "George Hett");
cy.get(".user-container").should("contain", "Barry Barry-Barroldsson");
});
it("A search is not affected by adding non alphanumeric characters", () => {
cy.login();
cy.get("#searchBox").type("Chris /.,[] Coding");
cy.get("#searchButton").click();
cy.get(".user-container").should("have.length", 2);
cy.get(".user-container").should("contain", "Chris Coding");
cy.get(".user-container").should("contain", "Paul Coding");
});
it("A user's search returns results for each word", () => {
cy.login();
cy.get("#searchBox").type("Chris Woodcock");
cy.get("#searchButton").click();
cy.get(".user-container").should("have.length", 3);
cy.get(".user-container").should("contain", "Adam Woodcock");
cy.get(".user-container").should("contain", "Kathleen Woodcock");
cy.get(".user-container").should("contain", "Chris Coding");
});
});
请您推荐我可以进行哪些调整以使此代码正常运行
你可能会发现这个效果更好,虽然我找不到任何容易因异步处理而失败的东西。
我假设 User.find()
returns 一个承诺。
const promises = searchArray.map((name) => {
return User.find({
firstName: { $regex: name, $options: "i" },
lastName: { $regex: name, $options: "i" },
})
})
Promise.all(promises).then((values) => {
const uniqueArray = values
.flat()
.filter((value, index, arr) => arr.indexOf(value) === index)
res.render("search/index", { users: uniqueArray });
})
cy.get(".user-container").should("have.length", 3);
应该处理测试结束时的任何滞后,但如果执行 multi-level 搜索可能需要超过 4 秒,您可能希望增加超时。
cy.get(".user-container", {timeout:10000})
.should("have.length", 3);
我通过将上面的内容重构为这个,通过更改 for each 循环来构建最终查询并将其传递给 find 语句,然后渲染效果非常好,从而设法解决了我自己的问题。我还重构了索引路由。
const User = require("../models/user");
const SearchController = {
Index: (req, res) => {
User.find().then((users) => {
res.render("search/index", { users: users });
});
},
Create: (req, res) => {
const searchArray = req.body.message.replace(/[\W_]+/g, " ").split(/[ ,]+/);
const findQuery = [];
searchArray.forEach((name) => {
const first = { firstName: { $regex: name, $options: "i" } };
const second = { lastName: { $regex: name, $options: "i" } };
findQuery.push(first, second);
});
User.find({ $or: findQuery }).then((users) => {
res.render("search/index", { users: users });
});
},
};
module.exports = SearchController;