MongoDB / Mongoose聚合或$或不按预期工作?

在html中有一些checkboxbutton,我想通过API on.click过滤AJAX结果。 有3种结果:upVote,noVote,downVoted。 根据哪个checkbox被选中,用户将看到upVote,noVote和downVoted文档的组合。

ajax调用API的URL,并且在通过node.js API中的以下循环运行之后,数据到达数据库调用,该循环通过string数组循环[“upVoted”,“noVote”,“downVoted” ](或其任何组合)并将true的布尔值赋给相应的variables:

var upVoted = false; var noVote = false; var downVoted = false; storyFiltering.forEach(storyFiltering); function storyFiltering(element, index, array) { if (element == 'upVoted') {upVoted = true} else if (element == 'noVote') {noVote = true} else if (element == 'downVoted') {downVoted = true} } console.log('upVoted: ' + upVoted + ', noVote: ' + noVote + ', downVoted: ' + downVoted); 

然后这些variables与每个文档中的投票的布尔值相匹配。

这里是数据库结构(投票只有一个布尔一次是真实的,其余的是假的):

 to: ["user1"], voting: { upVoted: true, noVote: false, downVoted: false }, rank: 4 to: ["user2"], voting: { upVoted: true, noVote: false, downVoted: false }, rank: 2 to: ["user1", "user2"], voting: { upVoted: true, noVote: false, downVoted: false }, rank: 1 to: ["user1", "user2"], voting: { upVoted: false, noVote: true, downVoted: false }, rank: 5 to: ["user1"], voting: { upVoted: false, noVote: false, downVoted: true }, rank: 3 

查找(或聚合)的结果将是一个过滤的数据callback,以匹配切换的投票布尔值,然后按降序排列它们。

切换user1的所有upVoted和noVote文档将返回:

 to: ["user1", "user2"], voting: { upVoted: true, noVote: false, downVoted: false }, rank: 1 to: ["user1"], voting: { upVoted: true, noVote: false, downVoted: false }, rank: 4 to: ["user1", "user2"], voting: { upVoted: false, noVote: true, downVoted: false }, rank: 5 

..只有为user1的upVote文档切换将返回:

 to: ["user1", "user2"], voting: { upVoted: true, noVote: false, downVoted: false }, rank: 1 to: ["user1"], voting: { upVoted: true, noVote: false, downVoted: false }, rank: 4 

..和在相同的模式下,切换为用户1的所有upVoted + noVote + downVoted文档将返回包括用户1的所有文档,按rank(1,3,4,5)sorting。while,symmestly切换用户2的所有downVoted文档将返回零文档。

在我看来,这是你的方法的基本问题。 你要做的是与用户界面进行交互,以“select”你想要在查询结果中显示的某些项目。 这一切都很好,但显然你似乎在寻找“统治所有人的一个问题”,而这正是你走向脱节的地方。

以你的第一个例子来说,你所有的“upvote”和“novote”文档的查询都是这样的。 现在也说明远离聚合,但同样适用于$matchpipe道的查询:

 db.collection.find({ "to": { "$in": ["user1"] }, "$or": [ { "voting.upVoted": true }, { "voting.noVote": true } ] }) 

这将返回您的预期结果作为$or认为这些条件的“任一”可以评估为true ,以满足比赛。 如前所述,MongoDB中的所有查询都是隐含的“和”查询,所以这里不需要额外的操作符。

在你的下一个例子中,你真的只需要你的一个标准是真实的,所以我们可以删除$or但我会留在这里以便稍后解释。

 db.collection.find({ "to": { "$in": ["user1"] }, "$or": [ { "voting.upVoted": true } ] }) 

再次,匹配您的预期结果,因为这返回“user1”存在“和”upVoted“值是true

但现在到你的界面交互和如何处理。 让我们说,你有来自你的界面的input,看起来像这样:

 { "to": "user1", "voting": { "upVoted": true, "downVoted": false, "noVote": true } } 

这确认了您的用户界面中为查询所做的基本select。 为了将这个过程“处理”到你想要的查询中,然后考虑下面的JavaScript代码,把它转换成你想要实现的任何语言。我只是假设所示的结构在一个名为request的variables中:

 var query = { "to": { "$in": [] }, "$or": [] }; for ( k in request ) { if ( k == "to" ) query.to["$in"].push( request.to ); if ( k == "voting" ) { for ( v in request[k] ) { if ( request[k][v] ) { // if that value is `true` var obj = {}; obj[ k + "." + v] = true; query["$or"].push( obj ); } } } } 

在数据上运行代码,生成的query对象现在看起来像:

 { "to" : { "$in" : [ "user1" ] }, "$or" : [ { "voting.upVoted" : true }, { "voting.noVote" : true } ] } 

这和我们先发出的查询是一样的,在request改变你的select,看看它在第二个例子中的样子:

 { "to": "user1", "voting": { "upVoted": true, "downVoted": false, "noVote": false } } 

结果query对象是:

 { "to" : { "$in" : [ "user1" ] }, "$or" : [ { "voting.upVoted" : true } ] } 

所有剩下要做的就是发出使用对象作为参数的查询:

 db.collection.find( query ) 

这就是你如何与你的界面中的数据交互。 您可以dynamic构build,而不是试图将查询中获取的所有值作为参数。