【问题标题】:performing query with priority in mongo在mongo中执行优先查询
【发布时间】:2016-01-12 06:12:21
【问题描述】:

示例文档:

{"name":"John", "age":35, "level":"trainee",.....}
  1. join_month=3 为最高优先级的员工(此类别中的员工首先出现)
  2. 作为主管的员工是第二优先级(出现在 #1 中的所有员工之后)
  3. 非马来西亚员工的优先级最低(排在所有其他员工之后)

例子:

  1. John 和 Jane 于 3 月加入
  2. 亚当、约翰和鲍勃是主管
  3. 上面提到的所有员工以及 Lee 都不是马来西亚人

预期结果是:

[John, Jane], [Adam, Bob], [Lee]

上面的方括号是为了表明同一个方括号内的顺序无关紧要。所以 Jane 也可能出现在 John 之前(因为它们的条件相同)。但 John 和 Jane 都必须出现在 Adam 和 Bob 之前,因为 join_month=3 的优先级高于 level=supervisor。并且还要注意,即使 John 也满足 level=supervisor 标准,他也不会再次被包括在内,因为他已经满足 join_month=3。

这在 MongoDB 中可行吗?

【问题讨论】:

    标签: sql mongodb mongodb-query aggregation-framework


    【解决方案1】:

    在您的 SQL 查询中,您不需要 UNION 运算符,因为您从同一个表中进行选择。您应该使用OR 运算符。 MongoDB 提供了一个 $or 运算符,它可以满足您的需求。

    您的 SQL 查询:

    SELECT NAME, AGE FROM EMPLOYEE 
    WHERE JOIN_MONTH=3
    OR LEVEL='SUPERVISOR'
    OR NATIONALITY <> 'MY'
    

    在 MongoDB 中:

    db.EMPLOYEE.find( { 
        "$or": [ 
            { "join_month": 3 }, 
            { "level": "supervisor" }, 
            { "nationality": { "$ne": "my" } } 
         ] },
         { "name": 1, "_id": 0, "age": 1 }
    )
    

    您需要的一切都在文档中。你应该从官方MongoDB CRUD Tutorials开始,看看SQL to MongoDB Mapping Chart

    如果要根据某些字段值对结果进行排序,则需要使用.aggregate() 方法,该方法提供对聚合管道的访问。管道中的第一个阶段是$match 阶段,您只选择那些符合您的条件的文档。这也减少了要在下一阶段处理的文档的大小,即此处的$project 阶段,您使用$cond 运算符返回一个字段的值,您将使用该字段对@987654328 中的查询结果进行排序@ 阶段。这个过程叫做"weighting"

    db.collection.aggregate([
        { "$match": { 
            "$or": [ 
                { "join_month": 3 }, 
                { "level": "supervisor" }, 
                { "nationality": { "$ne": "MY" } }
            ] 
        }}, 
        { "$project": { 
            "name": 1, 
            "age": 1,
            "_id": 0, 
            "criteria": { 
                "$cond": [ 
                   { "$eq": [ "$join_month",  3 ] }, 
                   3, 
                   { "$cond": [ 
                       { "$eq": [ "$level", "supervisor" ] }, 
                       2 , 
                       1 
                   ] } 
                ] 
            } 
        }}, 
        { "$sort":  { "criteria": -1 } }
    ])
    

    【讨论】:

      【解决方案2】:

      如果您需要排序,您可以使用如下聚合。

      pipeline = [
        {
          $match: {$or: [{join_months: 3}, {level: 'Supervisor'}, {nationality: {$ne: 'MY'}}
                        ]}
        },
        {
          $project: {
            name: 1,
            age: 1,
            join_priority: {$cond: [{$eq: ['$join_months', 3]}, 1, 0]},
            leve_priority: {$cond: [{$eq: ['$level', 'supervisor']}, 1, 0]},
          }
        },
        {
          $sort: {join_priority: -1, level_priority: -1}
        }
      ];
      db.mycollection.aggregate(pipeline);
      

      【讨论】:

        猜你喜欢
        • 2016-04-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多