我在使用mongoose从MongoDB检索数据时遇到以下问题。
这是我的架构:
const BookSchema = new Schema( { _id:Number, title:String, authors:[String], subjects:[String] } );
如您所见,我在对象中嵌入了2个数组,比方说作者的内容可以是这样的:authors:[“ Alex Ferguson”,“ Didier Drogba”,“ Cristiano Ronaldo”,“ Alex”] 我是什么我试图实现的是将所有Alex都放在阵列中。
到目前为止,如果它们与值完全匹配,我已经可以得到它们。但是,如果我尝试获取包含Alex的答案,则答案始终为[]。
我想知道的是如何使用find()来执行此操作,而无需执行map-reduce来创建视图或集合,然后在其上应用find()。
此处的代码适用于完全匹配
Book.find( {authors:req.query.q} , function(errs, books){ if(errs){ res.send(errs); } res.json(books); });
我尝试了一些方法,但是没有运气{authors:{$ elemMatch:req.query.q}} {authors:{$ in:[req.query.q]}}
这给了我一个错误,最重要的是,我在这里找到的另一篇文章效率很低。{$ where:this.authors.indexOf(req.query.q)!= -1}
而且我还尝试了{作者:{$ regex:“ ./ value / i”}}
map-reduce工作正常,我需要使用另一种方法使其工作,以查看哪种方法更好?
任何帮助是极大的赞赏。我敢肯定这很容易,但是我是NodeJS和Mongo的新手,我自己还无法弄清楚。
您几乎自己在标签中回答了这个问题。MongoDB有一个 $regex 运算符,它允许将正则表达式作为查询提交。因此,您查询包含“ Alex”的字符串,您可以这样做:
$regex
Books.find( { "authors": { "$regex": "Alex", "$options": "i" } }, function(err,docs) { } );
您也可以这样做:
Books.find( { "authors": /Alex/i }, function(err,docs) { } );
两者都是有效的,并且与您以正确的受支持语法尝试的方式不同,如文档中所示。
但是,当然,如果您实际上是在问“如何仅对那些与字符串中的“ Alex”匹配的结果获取“数组”结果?” 那么这有点不同。
超过复杂的匹配 一个 数组元素是域聚合框架(或可能的MapReduce,但这是很慢),在需要“过滤器”的数组的内容。
您的开始大体相同。此处的关键是对 $unwind 数组内容进行“反规范化”,以便能够作为单独的文档正确地“过滤”。然后,使用“匹配”文档重新构建数组。
$unwind
Books.aggregate( [ // Match first to reduce documents to those where the array contains the match { "$match": { "authors": { "$regex": "Alex", "$options": i } }}, // Unwind to "de-normalize" the document per array element { "$unwind": "$authors" }, // Now filter those document for the elements that match { "$match": { "authors": { "$regex": "Alex", "$options": i } }}, // Group back as an array with only the matching elements { "$group": { "_id": "$_id", "title": { "$first": "$title" }, "authors": { "$push": "$authors" }, "subjects": { "$first": "$subjects" } }} ], function(err,results) { } )