gpt4 book ai didi

mongodb - 如何在多个字段中搜索文本或表达式

转载 作者:行者123 更新时间:2023-12-04 18:29:21 24 4
gpt4 key购买 nike

db.movies.find({"original_title" : {$regex: input_data, $options:'i'}}, function (err, datares){
if (err || datares == false) {
db.movies.find({"release_date" : {$regex: input_data + ".*", $options:'i'}}, function (err, datares){
if(err || datares == false){
db.movies.find({"cast" : {$regex: input_data, $options:'i'}}, function (err, datares){
if(err || datares == false){
db.movies.find({"writers" : {$regex: input_data, $options:'i'}}, function (err, datares){
if(err || datares == false){
db.movies.find({"genres.name" : {$regex: input_data, $options:'i'}}, function (err, datares){
if(err || datares == false){
db.movies.find({"directors" : {$regex: input_data, $options:'i'}}, function (err, datares){
if(err || datares == false){
res.status(451);
res.json({
"status" : 451,
"error code": "dataNotFound",
"description" : "Invalid Data Entry."
});
return;
} else{
res.json(datares);
return;
}
});
} else {
res.json(datares);
return;
}
});
} else {
res.json(datares);
return;
}
});
} else {
res.json(datares);
return;
}
});
} else {
res.json(datares);
return;
}
});
} else {
res.json(datares);
return;
}
});


我正在尝试实现所谓的“多合一”搜索,以便每当用户键入任何类型的电影相关信息时,我的应用程序都将尝试返回所有相关信息。但是我已经注意到,该事务在后端可能很昂贵,有时主机确实很慢。


如何顺利关闭数据库连接,该在哪里使用?



我在这里读到最好不要在node.js >> Why is it recommended not to close a MongoDB connection anywhere in Node.js code?中关闭mongodb连接



通过使用嵌套的查找命令来实现一种多合一搜索的正确方法吗?

最佳答案

您当前的方法充满了问题,不需要这样做。您要做的就是在同一集合中的多个字段中搜索罐头收集的内容是纯字符串。它可能是一个正则表达式构造,但是我基于两种不区分大小写的纯文本搜索。

现在,我不确定是否要根据另一个查询的结果来运行一个查询,因为您不知道另一种方式,尽管这样做会更好。请相信我,这不是比这里列出的任何方法更好的方法,也并非如以下所示真正需要它:

正则表达式一次查询所有

这里的第一个基本选项是继续您的$regex搜索,但仅使用$or运算符在单个查询中:

db.movies.find(
{
"$or": [
{ "original_title" : { "$regex": input_data, "$options":"i"} },
{ "release_date" : { "$regex": input_data, "$options":"i"} },
{ "cast" : { "$regex": input_data, "$options":"i"} },
{ "writers" : { "$regex": input_data, "$options":"i"} },
{ "genres.name" : { "$regex": input_data, "$options":"i"} },
{ "directors" : { "$regex": input_data, "$options":"i"} }
]
},
function(err,result) {
if(err) {
// respond error
} else {
// respond with data or empty
}
}
);


这里的 $or条件有效地像“合并查询”一样工作,因为就文档选择而言,每个参数本身都被视为查询。因为这是一个查询,所以所有结果自然都在一起。

全文查询,多个字段

如果您不是真正使用从正则表达式操作(即 ^(\d+)\bword$)构建的“正则表达式”,那么最好使用MongoDB的“文本搜索”功能。只要您不查找通常不会被排除的内容,这种方法就很好,但是您的数据结构和主题实际上表明这是您可能在此处进行的操作的最佳选择。

为了能够执行文本搜索,首先需要创建一个 "text index",特别是在这里,您希望索引跨越文档中的多个字段。为此,放入外壳可能是最简单的:

db.movies.createIndex({
"original_title": "text",
"release_date": "text",
"cast" : "text",
"writers" : "text",
"genres.name" : "text",
"directors" : "text"
})


您也可以选择在文档中为索引中的字段分配“权重”。分配权重会将“优先级”赋予在搜索条件中匹配的字段中列出的术语。例如,“导演”的权重可能比“演员”的权重更高,因此“昆汀·塔伦蒂诺”的匹配项将“排名更高”结果是他是电影的导演(也是演员),而不仅仅是演员(就像罗伯特·罗德里格斯的大多数电影一样)。

但是有了这个,执行查询本身非常简单:

db.movies.find(
{ "$text": { "$search": input_data } },
function(err,result) {
if(err) {
// respond error
} else {
// respond with data or empty
}
}
);


真的几乎太简单了,但这就是全部。 $text查询运算符知道要使用所需的索引(每个集合只能有一个文本索引),然后它将浏览所有定义的字段。

这就是为什么我认为这最适合您的用例。

并行查询

我要在这里给出的最后一个替代方案是您仍然希望要求您需要运行单独的查询。我仍然否认您只需要查询如果先前的查询不返回结果,并且我还断言上述选项应被认为是“ first”(优先于文本搜索)。

编写依赖或链接的异步函数是一件很痛苦的事情,而且非常混乱。因此,我建议从另一个库依赖项中获取一些帮助,并在此处使用 node-async模块。

这提供了一个 aync.map.()方法,该方法非常适合通过并行运行事物来“组合”结果:

var fields = [
"original_title",
"release_date",
"cast",
"writers",
"genres.name",
"directors"
];

async.map(
fields,
function(field,callback) {
var search = {},
cond = { "$regex": input_data, "$options": "i" };

search[field] = cond; // assigns the field to search

db.movies.find(search,callback);
},
function(err,result) {
if(err) {
// respond error
} else {
// respond with data or empty
}
}
);


再说一遍。 .map()运算符获取每个字段并将其转置到查询中,查询又返回其结果。在所有查询都在最后一节中运行之后,可以将这些结果“合并”起来,就好像它们是单个结果集一样,就像其他替代方法在这里一样。

还有一个 .mapSeries()变体按顺序运行每个查询,如果您担心使用数据库连接和并发任务,则可以使用 .mapLimit()变体,但是对于如此小的体积,这应该不是问题。

我真的不认为此选项是必要的,但是如果仍然使用Case 1正则表达式语句,则由于并行运行查询,这种“可能”可能会带来一点性能上的好处,但是会增加内存和资源的消耗在您的应用程序中。

无论如何,这里的内容是“不要做您正在做的事情”,您不需要做的事,还有更好的方法来处理您要完成的任务。所有这些都意味着更清洁,更容易编写代码。

关于mongodb - 如何在多个字段中搜索文本或表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31859800/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com