2012-08-31 15 views
11

में समूह का चयन करें मैं ऐसा कुछ करने की कोशिश कर रहा हूं जो मुझे लगता है कि यह काफी सरल है। मान लीजिए मेरे पास मोंगो में रिकॉर्ड की एक श्रृंखला है जिसमें एक सामान्य कुंजी है, और गुणों की चर संख्या है। मैं रिकॉर्ड्स में नाम से सभी विशेषताओं और समूह का चयन करना चाहता हूं। उदाहरण* मोंगो एग्रीगेशन

{ Name: George, x: 5, y: 3 } 
{ Name: George, z: 9 } 
{ Name: Rob, x: 12, y: 2 } 

के लिए मैं एक सीएसवी कि इस तरह दिखता है निर्माण करने के लिए करना चाहते हैं:

Name  X Y Z 
George 5 3 9 
Rob  12 2 

DB.data.aggregate({ $group : { _id : "$Name" } }) 

की कोशिश की दुर्भाग्य से मैं रिकॉर्ड के रूप में सभी के नाम नहीं बल्कि के मिलन वापस मिल सभी संभावित गुण।

उत्तर

11

यदि आप विशेषताओं को जोड़ना चाहते हैं, तो आपको उन्हें group में जोड़ना होगा। उदाहरण के लिए, $addToSet का उपयोग कर एक्स, वाई, जेड गुण प्रत्येक नाम के आधार पर वर्गीकृत की अनूठी मूल्यों को खोजने के:

db.data.aggregate(
    { $group : { 
      _id : "$Name", 
      x: { $addToSet: "$x" }, 
      y: { $addToSet: "$y" }, 
      z: { $addToSet: "$z" }, 
    }} 
) 

रिटर्न:

{ 
    "result" : [ 
     { 
      "_id" : "Rob", 
      "x" : [ 
       12 
      ], 
      "y" : [ 
       2 
      ], 
      "z" : [ ] 
     }, 
     { 
      "_id" : "George", 
      "x" : [ 
       5 
      ], 
      "y" : [ 
       3 
      ], 
      "z" : [ 
       9 
      ] 
     } 
    ], 
    "ok" : 1 
} 
+0

धन्यवाद, मैंने $ push का उपयोग करके एक ही चीज़ की है और ऐसा लगता है कि यह काम करता है। मेरा अनुवर्ती प्रश्न यह होगा कि क्या यहां से फ्लैट सीएसवी को डेटा निर्यात करने का सबसे अच्छा तरीका है, परिणाम सेट में आंतरिक सरणी को अनदेखा करना? –

+0

मैं csv बनाने के लिए pymongo और पायथन का उपयोग कर रहा हूँ। एक शेष मुद्दा यह है कि जब मैं $ addToSet का उपयोग करता हूं, तो मैं प्रत्येक कुंजी के लिए परिणामों के सरणी बना रहा हूं, भले ही प्रत्येक कुंजी मान जोड़ी के लिए केवल एक अलग मूल्य हो। यह तब सीएसवी को बहुत बोझिल करने की प्रक्रिया बनाता है। क्या महत्वपूर्ण मूल्यों के सरणी बनाने से बचने का कोई तरीका है? –

+1

@RogerSanchez: '$ addToSet' या' $ push' सरणी मान वापस कर देगा, इसलिए आपको अपने CSV निर्यात में कुछ मालिश करना होगा या एक अलग समग्र फ़ंक्शन पर विचार करना होगा। उदाहरण के लिए, यदि सभी मान संख्यात्मक हैं और आपके पास प्रति फ़ील्ड केवल एक अद्वितीय मूल्य है तो आप ['$ max'] (http://docs.mongodb.org/manual/reference/aggregation/ का उपयोग करके दूर हो सकते हैं। #_S_max) इसके बजाए। यदि परिणाम मान * कभी-कभी * सरणी होते हैं, तो आपको अपने कोड में झुकाव करना होगा। यहां एक उदाहरण पायथन गिस्ट है जो मदद कर सकता है: [सीएसवी में उद्धृत तारों के लिए agg arrays flattening] (https://gist.github.com/a39b087da394b746e4fe)। – Stennie

0

यहाँ यह ऐसा करने का एक और तरीका है:

$connection = 'mongodb://localhost:27017'; 
$con  = new Mongo($connection); // mongo connection 

$db   = $con->test; /// database 
$collection = $db->prb; // table 

$keys  = array("Name" => 1,"x"=>1,"y"=>1,"z"=>1); 

// set intial values 
$initial = array("count" => 0); 

// JavaScript function to perform 
$reduce  = "function (obj, prev) { prev.count++; }"; 

$g   = $collection->group($keys, $initial, $reduce); 

echo "<pre>"; 
print_r($g); 

आप इस तरह जवाब कुछ (नहीं सटीक उत्पादन) मिल जाएगा:

0,123,
Array 
(
    [retval] => Array 
     (
      [0] => Array 
       (
        [Name] => George 
        [x] => 
        [y] => 
        [z] => 
        [count] => 2 
       ) 

      [1] => Array 
       (
        [Name] => Rob 
        [x] => 
        [y] => 
        [z] => 
        [count] => 1 
       ) 

     ) 

    [count] => 5 
    [keys] => 3 
    [ok] => 1 
) 
+1

जबकि 'समूह' एक व्यवहार्य विकल्प है जब तक कि आपका संग्रह शेड नहीं किया जाता है, आपको' गैर PHP प्रश्नों में PHP उदाहरणों का उपयोग नहीं करते हैं। – JohnnyHK

+1

@ जॉनीह एचके: मैं इसे लंबे समय से खोज रहा था, मुझे यह लिंक ढेर में मिला, लेकिन उसने मुझे उचित जवाब नहीं दिया, इसलिए जब मुझे जवाब मिला तो मैंने इसे यहां पोस्ट किया है, तो कोई इसे उपयोगी पा सकता है, अगर आप वास्तव में मुझे हटाना चाहते हैं कि मैं ऐसा कर सकता हूं। –

+0

आप तक, लेकिन इस मामले में 'कुल' एक बेहतर समाधान है और यदि संभव हो तो उदाहरण जावास्क्रिप्ट में होना चाहिए क्योंकि यह 'मूल' मोंगो भाषा है। कोई चिंता नहीं, बस आपको बताने के लिए। – JohnnyHK

-1

उपयोग $addToSet समूह के लिए, यह

db.data.aggregate(
    { $group : { 
      _id : "$Name", 
      x: { $addToSet: "$x" }, 
      y: { $addToSet: "$y" }, 
      z: { $addToSet: "$z" }, 
    }} 
) 
0

काम करेंगे Stennie से समाधान यह जानना चाहेंगे कि जिन विशेषताओं का आप संग्रह आप की क्वेरी रहे हैं में प्रत्येक मिलान के आइटम से लौटना चाहते की आवश्यकता है। यह हमेशा मामला नहीं है।

हमें इस समस्या को ग्रेल्स एप्लिकेशन पर लिखने के लिए हल करना था जिसे हम लिख रहे हैं।

हम इस तरह एक विधि को संभालने के लिए लिखा अनुरोध "एक्स से लगता है":

private List<DBObject> findDistinctPages(Map by) { 
    def command = 
     new GroupCommand(
       (DBCollection) db.pages, 
       new BasicDBObject(['url': 1]), 
       new BasicDBObject(by), 
       new BasicDBObject([:]), 
       'function (current, result) { for(i in current) { result[i] = current[i] } }', 
       '' 
     ) 
    db.pages.group(command).sort { it.title } 
} 

और फिर हमारे कोड के भीतर इसे कहते इस प्रकार है:

def pages = findDistinctPages([$or: [[type: 'channel'], [type: 'main']]]) 

यह काम करता है परिणामों पास करके GroupCommand के अंत में जावास्क्रिप्ट फ़ंक्शन के लिए प्रारंभिक क्वेरी का। मोंगो केवल प्रारंभिक क्वेरी में निर्दिष्ट विशेषताओं को लौटाता है और कुछ भी नहीं, इसलिए आपको दूसरी बार परिणामों को फिर से शुरू करना होगा, उन्हें मोंगो से शेष डेटा के साथ पॉप्युलेट करना होगा।

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