繁体   English   中英

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

[英]MongoDB/Mongoose aggregation or $or not working as expected?

在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获得的所有值作为查询中的参数。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM