第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

$ lookup之后的聚合過(guò)濾器

$ lookup之后的聚合過(guò)濾器

Cats萌萌 2019-09-24 16:23:38
如何在$ lookup之后添加過(guò)濾器,或者有其他方法可以執(zhí)行此操作?我的數(shù)據(jù)收集測(cè)試是:{ "_id" : ObjectId("570557d4094a4514fc1291d6"), "id" : 100, "value" : "0", "contain" : [ ] }{ "_id" : ObjectId("570557d4094a4514fc1291d7"), "id" : 110, "value" : "1", "contain" : [ 100 ] }{ "_id" : ObjectId("570557d4094a4514fc1291d8"), "id" : 120, "value" : "1", "contain" : [ 100 ] }{ "_id" : ObjectId("570557d4094a4514fc1291d9"), "id" : 121, "value" : "2", "contain" : [ 100, 120 ] }我選擇ID 100并匯總孩子:db.test.aggregate([ {  $match : {    id: 100  }}, {  $lookup : {    from : "test",    localField : "id",    foreignField : "contain",    as : "childs"  }}]);我回來(lái)了:{    "_id":ObjectId("570557d4094a4514fc1291d6"),  "id":100,  "value":"0",  "contain":[ ],  "childs":[ {        "_id":ObjectId("570557d4094a4514fc1291d7"),      "id":110,      "value":"1",      "contain":[ 100 ]    },    {        "_id":ObjectId("570557d4094a4514fc1291d8"),      "id":120,      "value":"1",      "contain":[ 100 ]    },    {        "_id":ObjectId("570557d4094a4514fc1291d9"),      "id":121,      "value":"2",      "contain":[ 100, 120 ]    }  ]}但我只希望與“值:1”匹配的子項(xiàng)最后,我希望得到以下結(jié)果:{    "_id":ObjectId("570557d4094a4514fc1291d6"),  "id":100,  "value":"0",  "contain":[ ],  "childs":[ {        "_id":ObjectId("570557d4094a4514fc1291d7"),      "id":110,      "value":"1",      "contain":[ 100 ]    },    {        "_id":ObjectId("570557d4094a4514fc1291d8"),      "id":120,      "value":"1",      "contain":[ 100 ]    }  ]}
查看完整描述

3 回答

?
絕地?zé)o雙

TA貢獻(xiàn)1946條經(jīng)驗(yàn) 獲得超4個(gè)贊

這里的問(wèn)題實(shí)際上是關(guān)于一些不同的東西,根本不需要$lookup。但是,對(duì)于僅從“ $ lookup之后過(guò)濾”標(biāo)題到達(dá)此處的任何人,這些都是適合您的技術(shù):


MongoDB 3.6-子管道

db.test.aggregate([

    { "$match": { "id": 100 } },

    { "$lookup": {

      "from": "test",

      "let": { "id": "$id" },

      "pipeline": [

        { "$match": {

          "value": "1",

          "$expr": { "$in": [ "$$id", "$contain" ] }

        }}

      ],

      "as": "childs"

    }}

])

較早-$ lookup + $ unwind + $ match合并

db.test.aggregate([

    { "$match": { "id": 100 } },

    { "$lookup": {

        "from": "test",

        "localField": "id",

        "foreignField": "contain",

        "as": "childs"

    }},

    { "$unwind": "$childs" },

    { "$match": { "childs.value": "1" } },

    { "$group": {

        "_id": "$_id",

        "id": { "$first": "$id" },

        "value": { "$first": "$value" },

        "contain": { "$first": "$contain" },

        "childs": { "$push": "$childs" }

     }}

])

如果您質(zhì)疑為什么不$unwind使用$filter該數(shù)組,請(qǐng)閱讀Aggregate $ lookup匹配管道中文檔的總大小超出了所有文檔的最大文檔大小,以了解為什么這是通常必需的并且是最佳方法。


對(duì)于MongoDB 3.6及更高版本,通常要在將所有內(nèi)容都返回到數(shù)組之前“過(guò)濾”外部集合的結(jié)果,來(lái)表達(dá)更具表現(xiàn)力的“子管道”。


回到答案,盡管實(shí)際上描述了為什么所提問(wèn)題根本不需要“加入”。


原版的

$lookup像這樣使用并不是在這里執(zhí)行所需操作的最“有效”方法。但是稍后會(huì)詳細(xì)介紹。


作為一個(gè)基本概念,只需$filter在結(jié)果數(shù)組上使用:


db.test.aggregate([ 

    { "$match": { "id": 100 } }, 

    { "$lookup": {

        "from": "test",

        "localField": "id",

        "foreignField": "contain",

        "as": "childs"

    }},

    { "$project": {

        "id": 1,

        "value": 1,

        "contain": 1,

        "childs": {

           "$filter": {

               "input": "$childs",

               "as": "child",

               "cond": { "$eq": [ "$$child.value", "1" ] }

           }

        }

    }}

]);

或$redact改為使用:


db.test.aggregate([ 

    { "$match": { "id": 100 } }, 

    { "$lookup": {

        "from": "test",

        "localField": "id",

        "foreignField": "contain",

        "as": "childs"

    }},

    { "$redact": {

        "$cond": {

           "if": {

              "$or": [

                { "$eq": [ "$value", "0" ] },

                { "$eq": [ "$value", "1" ] }

              ]

           },

           "then": "$$DESCEND",

           "else": "$$PRUNE"

        }

    }}

]);

兩者都得到相同的結(jié)果:


{  

  "_id":ObjectId("570557d4094a4514fc1291d6"),

  "id":100,

  "value":"0",

  "contain":[ ],

  "childs":[ {  

      "_id":ObjectId("570557d4094a4514fc1291d7"),

      "id":110,

      "value":"1",

      "contain":[ 100 ]

    },

    {  

      "_id":ObjectId("570557d4094a4514fc1291d8"),

      "id":120,

      "value":"1",

      "contain":[ 100 ]

    }

  ]

}

最重要的是,$lookup它本身不能“還”查詢(xún)以?xún)H選擇某些數(shù)據(jù)。因此,所有“過(guò)濾”操作都需要在$lookup


但是,實(shí)際上對(duì)于這種類(lèi)型的“自我連接”,您最好根本不使用它$lookup,并且完全避免額外讀取和“哈希合并”的開(kāi)銷(xiāo)。只需獲取相關(guān)項(xiàng)目,即可$group:


db.test.aggregate([

  { "$match": { 

    "$or": [

      { "id": 100 },

      { "contain.0": 100, "value": "1" }

    ]

  }},

  { "$group": {

    "_id": {

      "$cond": {

        "if": { "$eq": [ "$value", "0" ] },

        "then": "$id",

        "else": { "$arrayElemAt": [ "$contain", 0 ] }

      }

    },

    "value": { "$first": { "$literal": "0"} },

    "childs": {

      "$push": {

        "$cond": {

          "if": { "$ne": [ "$value", "0" ] },

          "then": "$$ROOT",

          "else": null

        }

      }

    }

  }},

  { "$project": {

    "value": 1,

    "childs": {

      "$filter": {

        "input": "$childs",

        "as": "child",

        "cond": { "$ne": [ "$$child", null ] }

      }

    }

  }}

])

由于我有意刪除了多余的字段,所以結(jié)果僅稍有不同。如果您確實(shí)要添加它們,請(qǐng)自己添加:


{

  "_id" : 100,

  "value" : "0",

  "childs" : [

    {

      "_id" : ObjectId("570557d4094a4514fc1291d7"),

      "id" : 110,

      "value" : "1",

      "contain" : [ 100 ]

    },

    {

      "_id" : ObjectId("570557d4094a4514fc1291d8"),

      "id" : 120,

      "value" : "1",

      "contain" : [ 100 ]

    }

  ]

}

因此,這里唯一真正的問(wèn)題是“過(guò)濾” null數(shù)組中的任何結(jié)果,該數(shù)組是在當(dāng)前文檔正在parent處理中時(shí)創(chuàng)建的$push。


您在這里似乎還缺少的是,您要查找的結(jié)果根本不需要聚合或“子查詢(xún)”。您已經(jīng)結(jié)束或可能在其他地方找到的結(jié)構(gòu)是“設(shè)計(jì)的”,以便您可以在單個(gè)查詢(xún)請(qǐng)求中獲得“節(jié)點(diǎn)”及其所有“子代”。


這意味著只有“ query”才是真正需要的,而數(shù)據(jù)收集(由于沒(méi)有真正“減少”任何內(nèi)容而已)的全部工作只是迭代游標(biāo)結(jié)果的功能:


var result = {};


db.test.find({

  "$or": [

    { "id": 100 },

    { "contain.0": 100, "value": "1" }

  ]

}).sort({ "contain.0": 1 }).forEach(function(doc) {

  if ( doc.id == 100 ) {

    result = doc;

    result.childs = []

  } else {

    result.childs.push(doc)

  }

})


printjson(result);

這做的完全一樣:


{

  "_id" : ObjectId("570557d4094a4514fc1291d6"),

  "id" : 100,

  "value" : "0",

  "contain" : [ ],

  "childs" : [

    {

      "_id" : ObjectId("570557d4094a4514fc1291d7"),

      "id" : 110,

      "value" : "1",

      "contain" : [

              100

      ]

    },

    {

      "_id" : ObjectId("570557d4094a4514fc1291d8"),

      "id" : 120,

      "value" : "1",

      "contain" : [

              100

      ]

    }

  ]

}

并證明您在這里真正需要做的就是發(fā)出“單個(gè)”查詢(xún)以選擇父項(xiàng)和子項(xiàng)。返回的數(shù)據(jù)是相同的,并且您在服務(wù)器或客戶(hù)端上所做的所有工作都在“按摩”為另一種收集的格式。


這是在這種情況下您可以“思考”如何在“關(guān)系”數(shù)據(jù)庫(kù)中做事的情況之一,而沒(méi)有意識(shí)到由于數(shù)據(jù)的存儲(chǔ)方式已“改變”,因此您不再需要使用同樣的方法。


這正是文檔示例“帶有子引用的模型樹(shù)結(jié)構(gòu)”結(jié)構(gòu)中的要點(diǎn),在該示例中可以輕松地在一個(gè)查詢(xún)中選擇父級(jí)和子級(jí)。


查看完整回答
反對(duì) 回復(fù) 2019-09-24
?
長(zhǎng)風(fēng)秋雁

TA貢獻(xiàn)1757條經(jīng)驗(yàn) 獲得超7個(gè)贊

就“性能”而言$lookup,實(shí)際上是在“服務(wù)器”上進(jìn)行“兩個(gè)”查詢(xún)?!翱蛻?hù)端”可以執(zhí)行“兩個(gè)”查詢(xún),但是當(dāng)然會(huì)涉及網(wǎng)絡(luò)和響應(yīng)開(kāi)銷(xiāo),這將減慢該過(guò)程。因此,為什么要這么做$lookup。但是我也是說(shuō)您的案子不需要這個(gè)。所有項(xiàng)目已經(jīng)在同一個(gè)集合中,因此只需簡(jiǎn)單地選擇它們并$group相應(yīng)地選擇它們即可。就“性能”而言,到目前為止,這是三個(gè)中更好的選擇。

查看完整回答
反對(duì) 回復(fù) 2019-09-24
?
慕姐4208626

TA貢獻(xiàn)1852條經(jīng)驗(yàn) 獲得超7個(gè)贊

我認(rèn)為您仍然停留在“關(guān)系思考”中,這使您在實(shí)際上不需要“子查詢(xún)”或“自我加入”的情況下也不需要。在此處添加了純“無(wú)聚合”方法來(lái)說(shuō)明這一點(diǎn)。

查看完整回答
反對(duì) 回復(fù) 2019-09-24
  • 3 回答
  • 0 關(guān)注
  • 1109 瀏覽
慕課專(zhuān)欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢(xún)優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)