mongodb查询的意外结果?

时间:2019-02-25 10:12:07

标签: mongodb mongodb-query

我在mongodb中有两个集合,并通过使用$ match和$ sort来获取数据库中的记录,我在查询中也使用了find().sort(),但是查询产生的结果是不同的。首先,我使用以下查询从section集合中获取记录:-

查询1

db.section.find({"status":1}).sort({"display_order":1}).pretty()

上述查询产生的结果是:-

{ "_id" : 1, "name" : "name", "status" : 1 }
{ "_id" : 2, "name" : "email", "status" : 1 }

并使用$lookup从两个集合中获取记录,并结合一个原键,查询如下所示:-

查询2

db.lead_section.aggregate([ 
  {$lookup: { "localField": "_id", 
              "from": "lead_field",   
              "foreignField": "lead_section_id", 
              "as": "custom_fields" }}, 
  {"$unwind": "$custom_fields"}, 
  {$match: {status: 1, "custom_fields.status": {$exists: true, $eq: 1}}}, 
  {"$sort": {"custom_fields.display_order": 1}}, 
  {"$group": { "_id":"$_id", "name":{"$first": "$name"}, 
               "status":{"$first": "$status"}, 
               "display_order": {"$first": "$display_order"},
               "custom_fields": {"$push": "$custom_fields"}}},
  {"$sort": {"display_order": 1}} ]).pretty()

上面的查询将产生类似

的结果
 {
  "_id" : 2,
  "name" : "email",
  "status" : 1,
  "display_order" : null,
  "custom_fields" : [
    {
        "_id" : 2,
        "lead_section_id" : 2,
        "name" : "email2",
        "status" : 1
    }
  ]
}
{
  "_id" : 1,
  "name" : "name",
  "status" : 1,
  "display_order" : null,
  "custom_fields" : [
    {
        "_id" : 1,
        "lead_section_id" : 1,
        "name" : "name2",
        "status" : 1
    }
  ]
}

我也如下更改查询

 db.lead_section.aggregate([ 
  {$lookup: { "localField": "_id", 
              "from": "lead_field",   
              "foreignField": "lead_section_id", 
              "as": "custom_fields" }}, 
  {"$unwind": "$custom_fields"}, 
  {$match: {status: 1, "custom_fields.status": {$exists: true, $eq: 1}}}, 
  {"$sort": {"custom_fields.display_order": 1}}, 
  {"$group": { "_id":"$_id", "name":{"$first": "$name"}, 
               "status":{"$first": "$status"},
               "custom_fields": {"$push": "$custom_fields"}}},
  {"$sort": {"display_order": 1}} ]).pretty()

此查询将删除display_order字段,其余结果将相同。

query 1query 2查询之间有什么区别,我将如何产生两个查询的相同结果。

($sort with display_order is necessary)

任何人都可以帮助我解决这个问题。 谢谢。

2 个答案:

答案 0 :(得分:0)

我认为您首先必须使用display_order值保存0字段,然后在查询中首先必须执行db.section.find({"status":1}).sort({"display_order":1,"_id":1}).pretty()

这意味着如果存在display_order值,则它将使用display_order对其进行排序,或者将根据_id对该数据进行排序

查询2中的排序相同,如下所示:-

 db.lead_section.aggregate([ 
    {$lookup: { "localField": "_id", 
                "from": "lead_field", 
                "foreignField": "lead_section_id", 
                "as": "custom_fields" }}, 
    {"$unwind": "$custom_fields"}, 
    {$match: {status: 1, "custom_fields.status": {$exists: true, $eq: 1}}}, 
    {"$sort": {"custom_fields.display_order": 1}}, 
    {"$group": { "_id":"$_id", 
                 "name":{"$first": "$name"}, 
                 "status":{"$first": "$status"}, 
                 "display_order": {"$first": "$display_order"}, 
                 "custom_fields": {"$push": "$custom_fields"}}}, 
    {"$sort": {"display_order": 1, "_id":1}} ]).pretty()

这将为您服务:)

答案 1 :(得分:0)

在这里,我有两个集合 Users User Profile , 下面的方法将匹配请求的字段,还将两个集合组合并抛出所需的输出:

const getUserData = async (userId) => {

            const getUserDataByUserId = await userDataModel.aggregate([
                {
                    $match: {
                        userId: userId
                    }
                }, {
                    $lookup: {
                        from: 'user_profiles',
                        localField: 'userId',
                        foreignField: 'userId',
                        as: 'users'
                    }
                }, {
                    $replaceRoot: {
                        newRoot: {
                            $mergeObjects: [{
                                $arrayElemAt: ["$users", 0]
                            }, "$$ROOT"]
                        }
                    }
                }, {
                    $project: {
                        fromItems: 0
                    }
                }
            ]);

            return getUserDataByUserId;
        }