在HTML中有一些复选框按钮,我想通过AJAX上的API on.click过滤结果。有3种结果:upVoted,noVote,downVoted。根据选中哪个复选框,将向用户显示upVoted,noVote和downVoted文档的组合。
ajax调用API的URL,并在node.js API中通过以下循环运行后,数据正确到达数据库调用,该循环遍历字符串数组[“ upVoted”,“ noVote”,“ downVoted” ](或其任意组合),并将true的布尔值分配给相应的变量:
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);
然后,这些变量将与每个文档中投票的布尔值匹配。
这是数据库结构(一次投票只有一个布尔值为真,其余为false):
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
查找(或汇总)的结果将是过滤后的数据以匹配切换后的投票布尔值的回调,然后按降序对它们进行排序。
切换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的所有文档,并按等级(1、3、4、5)排序。 ,切换用户2的所有downVoted文档将返回零文档。
最佳答案
我认为这是您的方法遇到的基本问题。您想要做的是与用户界面进行交互,该用户界面“选择”您要显示在查询结果中的某些项目。没关系,但是显然您似乎在寻找“一个查询来统治所有对象”,这就是您要解决的问题。
以您的第一个示例为例,您对所有“ upvote”和“ novote”文档的查询都会这样显示。还说明了现在不进行聚合,但是对$match
管道的查询也是如此:
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
的位置。现在,进入您的界面交互以及如何处理。假设您有来自您的界面的输入,如下所示:
{
"to": "user1",
"voting": {
"upVoted": true,
"downVoted": false,
"noVote": true
}
}
这将确认您在用户界面中为查询所做的基本选择。为了将其“处理”为所需的查询,然后考虑以下JavaScript代码,以将其翻译为您要实现的任何语言。我将假设该结构如图所示位于称为
request
的变量中: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
中更改您的选择以使其看起来与第二个示例中的方式相同:{
"to": "user1",
"voting": {
"upVoted": true,
"downVoted": false,
"noVote": false
}
}
生成的
query
对象为:{
"to" : {
"$in" : [
"user1"
]
},
"$or" : [
{
"voting.upVoted" : true
}
]
}
剩下要做的就是发出使用对象作为参数的查询:
db.collection.find( query )
这样便可以与界面中的数据进行交互。您可以动态构建,而不是尝试将在
response
中获得的所有值都作为查询中的参数。