使用 mongodb 查找结果

Posted

技术标签:

【中文标题】使用 mongodb 查找结果【英文标题】:Finding results with mongodb 【发布时间】:2021-05-18 21:59:58 【问题描述】:

我有一个充满技能的数据库,我正在尝试制作一个 info cmd,如果你输入技能名称,你会得到一些关于它的信息。有些技能是2-3个参数。例如“动物呼唤”。我希望能够通过输入 !info animal call 和例如 !info ani call 之类的简短内容来找到我在 mongodb 中的技能

关于这个的问题是,如果我尝试使用 !info ani call 找到它,它不会因此显示出来。

这是我的代码:

let skill = args.slice(0).join(" ");

const skillDB = await Skill.find()

for (let i = 0; i < skillDB.length; i++) 
 if (skillDB[i].skillName.toLowerCase().includes(`$skill.toLowerCase()`)) 
  const embed = new MessageEmbed()
  .setDescription(`\`$skillDB[i].skillIcon\` $skillDB[i].skillName`)
  .setImage(skillDB[i].skillImg)
  return message.channel.send(embed)
 

【问题讨论】:

【参考方案1】:

我认为您需要在这里使用某种正则表达式。您可以通过.* 加入它们并将其用作正则表达式,而不是通过空格joining 参数。

.*匹配任何字符,所以当你加入['ani', 'call']时,它会变成一个类似'ani.*call'的字符串。作为正则表达式模式,/ani.*call/ 匹配任何同时包含 anicall 的字符串(按此顺序)。

const args = ['ani', 'call']
const regex = new RegExp(args.join('.*'), 'i')

console.log(`Words matching $regex:`)
console.log('animal', regex.test('animal'))
console.log('animal call', regex.test('animal call'))
console.log('anime caller', regex.test('anime caller'))
console.log('anicall', regex.test('anicall'))
console.log('animal cruelty', regex.test('animal cruelty'))
console.log('anemia caribou', regex.test('anemia caribou'))

如果您不想匹配没有任何附加字符的单词,可以使用.+ 连接单词。使用+ 符号要求两个字符串之间至少有一个额外的字符;这样就不会匹配anicall:

const args = ['ani', 'call']
const regex = new RegExp(args.join('.+'), 'i')

console.log(`Words matching $regex:`)
console.log('animal', regex.test('animal'))
console.log('animal call', regex.test('animal call'))
console.log('anime caller', regex.test('anime caller'))
console.log('anicall', regex.test('anicall'))
console.log('animal cruelty', regex.test('animal cruelty'))
console.log('anemia caribou', regex.test('anemia caribou'))

您也可以使用 [a-z\s]+ 来仅接受 a-z 范围内的字符和空格:

const args = ['ani', 'call']
const regex = new RegExp(args.join('[a-z\\s]+'), 'i')

console.log(`Words matching $regex:`)
console.log('animal', regex.test('animal'))
console.log('animal call', regex.test('animal call'))
console.log('anime caller', regex.test('anime caller'))
console.log('anicall', regex.test('anicall'))
console.log('animal cruelty', regex.test('animal cruelty'))
console.log('anemia caribou', regex.test('anemia caribou'))

使用您当前的代码,您可以使用.test() 方法而不是.includes()。它搜索正则表达式和指定字符串之间的匹配项。

您还可以使用for ... of 循环而不是 for 循环来使其更具可读性:

const regex = new RegExp(args.join('[a-z\\s]+'), 'i');
const skills = await Skill.find();
const embed = new MessageEmbed();

for (let skill of skills) 
  if (regex.test(skill.skillName)) 
    embed
      .setDescription(`\`$skill.skillIcon\` $skill.skillName`)
      .setImage(skill.skillImg);

    return message.channel.send(embed);
  

不过,我不确定您为什么要从数据库中获取所有技能。您还可以将find()findOne() 与上面的正则表达式一起使用,以仅获取您需要的数据:

const regex = new RegExp(args.join('[a-z\\s]+'), 'i');
// findOne returns a single object or null if not found
const skill = await Skill.findOne(
  skillName:  $regex: regex ,
);

if (!skill) 
  return message.channel.send(
    `Oops, I couldn't find any skill in the database for \`$args.join(' ')\``,
  );


const embed = new MessageEmbed()
  .setDescription(`\`$skill.skillIcon\` $skill.skillName`)
  .setImage(skill.skillImg);

return message.channel.send(embed);

【讨论】:

嘿,这行得通,但如果我也想用 + 搜索怎么办?比如一个叫做“De+S”的技能。那个正则表达式不允许我搜索。 您可以将+ 符号添加到您的角色类中:args.join('[a-z\\s+]+'), 'i')

以上是关于使用 mongodb 查找结果的主要内容,如果未能解决你的问题,请参考以下文章

MongoDB - 查找 - 多个集合 - 结果在一个数组中

MongoDB 查找并映射 2 个结果数组

具有 3 个级别的 MongoDB 嵌套查找并将新值附加到结果文档

Mongodb 按今天的日期查找创建的结果

MongoDB 查找和展开没有给出正确的结果

在 mongodb 中添加额外字段的查找