2015-03-15 7 views
5

में $ पुश-आईएनजी नल से बचने के लिए कैसे करें यदि फ़ील्ड मौजूद नहीं है तो $ पुश नल को एकत्रित कर रहा है। मैं इससे बचना चाहता हूं।मोंगो एग्रीगेशन फ्रेमवर्क

क्या $ पुश ऑपरेटर के लिए उप अभिव्यक्ति करने का कोई तरीका है इस तरह से कि शून्य मान छोड़े जाएंगे और परिणामी सरणी में नहीं धकेल दिए जाएंगे?

उत्तर

4

यह वास्तव में पूरी तरह स्पष्ट नहीं है कि आपका विशिष्ट मामला उदाहरण के बिना क्या है। $ifNull ऑपरेटर है जो "कुछ और" के साथ एक शून्य मान या अनुपलब्ध फ़ील्ड को "प्रतिस्थापित" कर सकता है, लेकिन वास्तव में "छोड़ना" संभव नहीं है।

यह कहा गया है कि, आप अपने वास्तविक उपयोग मामले के आधार पर परिणामों को हमेशा "फ़िल्टर" कर सकते हैं।

अपने परिणामी डेटा वास्तव में है, तो एक "सेट" और आप एक MongoDB संस्करण है 2.6 या अधिक से अधिक है तो आप $addToSet से कुछ मदद के साथ $setDifference उपयोग कर सकते हैं null मानों की संख्या है कि शुरू में रखा जाता है कम करने के लिए:

db.collection.aggregate([ 
    { "$group": { 
     "_id": "$key", 
     "list": { "$addToSet": "$field" } 
    }}, 
    { "$project": { 
     "list": { "$setDifference": [ "$list", [null] ] } 
    }} 
]) 

तो केवल null होगा और फिर $setDifference ऑपरेशन तुलना में "फिल्टर" करेगा।

पहले के संस्करणों में

या जब मूल्यों वास्तव में "अद्वितीय" नहीं हैं और नहीं एक "सेट", तो आप "फिल्टर" प्रसंस्करण द्वारा $unwind और $match साथ:

db.collection.aggregate([ 
    { "$group": { 
     "_id": "$key", 
     "list": { "$push": "$field" } 
    }}, 
    { "$unwind": "$list" }, 
    { "$match": { "list": { "$ne": null } }}, 
    { "$group": { 
     "_id": "$_id", 
     "list": { "$push": "$list" } 
    }} 
]) 

आप नहीं करना चाहते हैं

db.collection.aggregate([ 
    { "$group": { 
     "_id": "$key", 
     "list": { "$push": "$field" }, 
     "count": { 
      "$sum": { 
       "$cond": [ 
        { "$eq": { "$ifNull": [ "$field", null ] }, null }, 
        0, 
        1 
       ] 
      } 
     } 
    }}, 
    { "$unwind": "$list" }, 
    { "$match": { 
     "$or": [ 
      { "list": { "$ne": null } }, 
      { "count": 0 } 
     ] 
    }}, 
    { "$group": { 
     "_id": "$_id", 
     "list": { "$push": "$list" } 
    }}, 
    { "$project": { 
     "list": { 
      "$cond": [ 
       { "$eq": [ "$count", 0 ] }, 
       { "$const": [] }, 
       "$list" 
      ] 
     } 
    }} 
]) 

एक अंतिम $project के साथ: सरणियों कि अंत होगा "खाली" क्योंकि वे निहित "कुछ भी नहीं लेकिन" null की "विनाशकारी" होने के लिए, तो आप एक गिनती उपयोग $ifNull और मैच की स्थिति पर रखने किसी भी सरणी को प्रतिस्थापित करना जिसमें केवल null मान केवल रिक्त सरणी ऑब्जेक्ट के साथ होते हैं।

+0

आपने मुझे अभी मस्तिष्क-मंदी से बचाया है! धन्यवाद – mhlavacka

4

बिट पार्टी के लिए देर हो चुकी है, लेकिन ..

मैं एक ही बात करना चाहता था, और पाया कि मैं इसे इस तरह एक अभिव्यक्ति के साथ पूरा कर सकते हैं:

// Pushes events only if they have the value 'A' 
    "events": { 
    "$push": { 
     "$cond": [ 
     { 
      "$eq": [ 
      "$event", 
      "A" 
      ] 
     }, 
     "A", 
     "$noval" 
     ] 
    } 
    } 

सोच है कि यहाँ है जब आप

{ "$push": "$event" } 

तो ऐसा लगता है कि यह केवल गैर-शून्य मानों को धक्का देता है।

तो मैंने एक कॉलम बनाया जो मौजूद नहीं है, $ noval, को मेरे $ cond की झूठी स्थिति के रूप में वापस करने के लिए।

ऐसा लगता है कि यह काम करता है। मुझे यकीन नहीं है कि यह गैर-मानक है और इसलिए एक दिन तोड़ने के लिए अतिसंवेदनशील है लेकिन

+0

यह काम करता है, लेकिन इसका उपयोग इंडेक्स के साथ नहीं किया जा सकता है और यह देखने के लिए हमेशा 'collscan' का उपयोग करेगा कि गैर-मौजूदा मान मौजूद है या नहीं। – Redsandro

+0

मेरे मामले में काम किया, धन्यवाद। आपने मुझे बहुत समय बचाया – Kostanos

संबंधित मुद्दे