सभी मौजूदा फ़ील्ड शामिल करें और दस्तावेज़ में नए फ़ील्ड जोड़ें


123

मैं एक $ परियोजना एकत्रीकरण चरण को परिभाषित करना चाहूंगा जहां मैं इसे सभी नए क्षेत्रों को सूचीबद्ध करने के लिए बिना किसी नए फ़ील्ड को जोड़ने और सभी मौजूदा फ़ील्ड्स को शामिल करने का निर्देश दे सकता हूं।

मेरा दस्तावेज़ इस तरह दिखता है, कई क्षेत्रों के साथ:

{
    obj: {
        obj_field1: "hi",
        obj_field2: "hi2"
    },
    field1: "a",
    field2: "b",
    ...
    field26: "z"
}

मैं इस तरह एक एकत्रीकरण ऑपरेशन करना चाहता हूं:

[
    {
        $project: {
            custom_field: "$obj.obj_field1",
            //the next part is that I don't want to do
            field1: 1,
            field2: 1,
            ...
            field26: 1
        }
    },
    ... //group, match, and whatever...
]

क्या कोई "सभी फ़ील्ड शामिल करें" कीवर्ड जैसा है जिसे मैं इस मामले में उपयोग कर सकता हूं, या किसी अन्य तरीके से हर क्षेत्र को अलग से सूचीबद्ध करने से बचने के लिए?


1
यह फीचर अगली बड़ी रिलीज 2.6 में आ रहा है। आप इसे अस्थिर देव शाखा पर आज़मा सकते हैं - संपूर्ण आने वाले दस्तावेज़ को संदर्भित करने के लिए "$ $ रूट" का उपयोग करें। इस टिकट में विवरण देखें: jira.mongodb.org/browse/SERVER-5916
Asya Kamsky

1
इस मुद्दे को कुछ अन्य उपयोगी और विभिन्न उत्तरों के साथ stackoverflow.com/questions/20497499/… पर भी उठाया गया है।
विंस बॉड्रेन

जवाबों:


168

4.2+ में, आप $setएकत्रीकरण पाइपलाइन ऑपरेटर का उपयोग कर सकते हैं जो $addFields3.4 में जोड़े जाने वाले उपनाम के अलावा और कुछ नहीं है

$addFieldsचरण एक के बराबर है $projectचरण कि स्पष्ट रूप से इनपुट दस्तावेजों में सभी मौजूदा क्षेत्रों को निर्दिष्ट करता है और नए क्षेत्रों को जोड़ता है।

db.collection.aggregate([
    { "$addFields": { "custom_field": "$obj.obj_field1" } }
])

2
किसी भी विचार कैसे सी # ड्राइवर में इसका इस्तेमाल करने के लिए? ऐसा लगता है कि इसका अस्तित्व नहीं है
होमम

मैं C # ड्राइवर से परिचित नहीं हूँ, लेकिन $addFieldsMongoDB 3.4 में नया है जो C # ड्राइवर संस्करण 2.5+
styvane

मैं सी # ड्राइवर में ऐसा करने के लिए एक रास्ता खोज रहा हूं, और अब तक यह ऐसा करने के तरीके की तरह लग रहा है जैसे कि कुछ का उपयोग करना होगाIAggregateFluent<TResult>.AppendStage(new JsonPipelineStageDefinition<TInput, TOutput>("{ $addFields : { myField: 'myValue' }}")
sboisse

4
मुझे पता चला कि यदि आप एक ही फ़ील्ड का नाम निर्दिष्ट करते हैं तो यह एक फ़ील्ड को भी बदल सकता है
CME64

79

रूट डॉक्यूमेंट को रेफर करने के लिए आप $ $ ROOT का उपयोग कर सकते हैं । इस दस्तावेज़ के सभी फ़ील्ड एक फ़ील्ड में रखें और उसके बाद प्राप्त करने का प्रयास करें (आपके क्लाइंट सिस्टम के आधार पर: जावा, सी ++, ...)

 [
    {
        $project: {
            custom_field: "$obj.obj_field1",
            document: "$$ROOT"

        }
    },
    ... //group, match, and whatever...
]

17
लेकिन यह एक एम्बेडेड डॉक का निर्माण करेगा जिसे documentएक मर्ज किए गए डॉक्टर के लिए एक विकल्प कहा जाता है जो अच्छा होगा ...
अलेक्जेंडर सुरफेल

2
क्या किसी को एम्बेडेड दस्तावेज़ बनाए बिना सभी प्रमुख मूल्य जोड़े से गुजरने के समाधान का पता है?
ugotchi

11
अपनी साँसे थामो। MongoDB 3.4 $ addFields एकत्रीकरण चरण के साथ आएगा जो ऐसा करता है। Stackoverflow.com/a/24557029/4653485 देखें ।
Jérôme

यह सबसे अच्छा वर्तमान समाधान प्रतीत होता है, जैसा कि आप कर सकते हैं (कम से कम जेएस में) तो नए custom_fieldसंलग्न के साथ अपनी मूल वस्तु के पुनर्निर्माण के लिए प्रसार ऑपरेटर का उपयोग करें । const newObj = { ...result.document, custom_field: result.custom_field }
ffritz

7

>>> कुछ ऐसा है "सभी फ़ील्ड शामिल करें" कीवर्ड जो मैं इस मामले में उपयोग कर सकता हूं या कुछ अन्य समाधान?

Unfortunaly, एकत्रीकरण ऑपरेशन में "सभी क्षेत्रों को शामिल करने" के लिए कोई ऑपरेटर नहीं है। एकमात्र कारण, क्यों, क्योंकि एकत्रीकरण ज्यादातर संग्रह फ़ील्ड (डेटा, एवीजी, आदि) से डेटा को समूह / गणना करने के लिए बनाया गया है और सभी संग्रह के फ़ील्ड को वापस करना प्रत्यक्ष उद्देश्य नहीं है।


... क्योंकि एकत्रीकरण ज्यादातर समूह के लिए बनाया गया है / संग्रह क्षेत्रों से डेटा की गणना ... वास्तव में सबसे अच्छा जवाब!
felipsmartins

1
आपके पास posts_id, शीर्षक, बॉडी, पसंद फ़ील्ड्स के साथ एक संग्रह है । पसंद फ़ील्ड उपयोगकर्ता का एक सरणी है, जो पोस्ट पसंद करता है। आप सभी पोस्ट को सभी _id, शीर्षक, बॉडी, लाइक के साथ कैसे सूचीबद्ध कर सकते हैं? सभी क्षेत्रों को वापस करना इस मामले में एक सीधा उद्देश्य है।
doc_id

3

संस्करण 2.6.4 के रूप में, Mongo DB में $projectएकत्रीकरण पाइपलाइन के लिए ऐसी कोई सुविधा नहीं है । के लिए डॉक्स से $project:

पाइपलाइन में अगले चरण के लिए केवल निर्दिष्ट फ़ील्ड के साथ दस्तावेजों के साथ गुजरता है। निर्दिष्ट फ़ील्ड इनपुट दस्तावेजों या नए गणना किए गए फ़ील्ड से मौजूदा फ़ील्ड हो सकते हैं।

तथा

_Id फ़ील्ड आउटपुट दस्तावेज़ों में शामिल डिफ़ॉल्ट रूप से है। आउटपुट दस्तावेज़ों में इनपुट दस्तावेज़ों से अन्य फ़ील्ड्स को शामिल करने के लिए, आपको स्पष्ट रूप से $ परियोजना में समावेश को निर्दिष्ट करना होगा।


2

अपने दस्तावेज़ में नए फ़ील्ड जोड़ने के लिए आप उपयोग कर सकते हैं $addFields

डॉक्स से

और आपके दस्तावेज़ के सभी क्षेत्रों में, आप उपयोग कर सकते हैं $$ROOT

db.collection.aggregate([

{ "$addFields": { "custom_field": "$obj.obj_field1" } },
{ "$group": {
        _id : "$field1",
        data: { $push : "$$ROOT" }
    }}
])

0

@Deka उत्तर के अनुसार, c # mongodb ड्राइवर 2.5 के लिए आप नीचे दिए गए सभी कुंजी के साथ समूहीकृत दस्तावेज़ प्राप्त कर सकते हैं;

var group = new BsonDocument
{
 { "_id", "$groupField" },
 { "_document", new BsonDocument { { "$first", "$$ROOT" } } }
};

ProjectionDefinition<BsonDocument> projection = new BsonDocument{{ "document", "$_document"}};
var result = await col.Aggregate().Group(group).Project(projection).ToListAsync();

// For demo first record 
var fistItemAsT = BsonSerializer.Deserialize<T>(result.ToArray()[0]["document"].AsBsonDocument);
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.