2014-05-08 36 views
1
db.test.aggregate([ 
    { "$unwind": "$Data" }, 
    { "$sort" : { "Data.cost" : -1 } }, 
    { "$group":{ 
     "_id":"$Data.name", 
     "Data":{ "$push": "$Data" } 
    }} 
]) 

我上述查詢燒製合併內陣列。它給我的結果如下:,通過使用公用數據

{ 
    "result":[{ 
     "_id" : "abc" 
     "Data" : [ 
      { 
       "uid" : "1...A", 
       "name" : "abc", 
       "city" : "Paris", 
       "description" : { 
        "things" : [ 
         { 
          "fruit" : { 
           "fruit_name" : "apple", 
           "fruit_rate" : "4 USD" 
          }, 
          "flower" : { 
           "flower_name" : "rose", 
           "flower_rate" : "2 USD" 
          } 
         } 
        ] 
       }, 
       "cost" : "6 USD" 
      }, 
      { 
       "uid" : "1...B", 
       "name" : "abc", 
       "city" : "Paris", 
       "description" : { 
        "things" : [ 
         { 
          "fruit" : { 
           "fruit_name" : "cherry", 
           "fruit_rate" : "3 USD" 
          }, 
          "flower" : { 
           "flower_name" : "orchid", 
           "flower_rate" : "2 USD" 
          } 
         } 
        ] 
       }, 
       "cost" : "5 USD" 
      } 
     ] 
    }] 
} 

但我不希望這樣的結果。我想合併「描述」這兩個數據的數組如果「名稱」是相同的。 像下面提及:

{ 
    "result":[{ 
     "_id" : "abc" 
     "Data" : [ 
      { 
       "uid" : "1...A", 
       "name" : "abc", 
       "city" : "Paris", 
       "description" : { 
        "things" : [ 
         { 
          "fruit" : { 
           "fruit_name" : "apple", 
           "fruit_rate" : "4 USD" 
          }, 
          "flower" : { 
           "flower_name" : "rose", 
           "flower_rate" : "2 USD" 
          } 
         } 
        ] 
       }, 
       "description" : { 
        "things" : [ 
         { 
          "fruit" : { 
           "fruit_name" : "cherry", 
           "fruit_rate" : "3 USD" 
          }, 
          "flower" : { 
           "flower_name" : "orchid", 
           "flower_rate" : "2 USD" 
          } 
         } 
        ] 
       }, 
       "cost" : "6 USD" 
      } 
     ] 
    }] 
} 

是否有可能得到結果也是這樣嗎?我在查詢中必須做什麼更改?

謝謝。

+1

爲什麼你的結果中有2描述和成本?我不認爲這是一個有效的JSON格式。 – yaoxing

回答

1

你已經構建了你想要的結果的方式根本不可能。原因是你基本上違背了Hash Table或字典/關聯數組(無論哪個術語更適合你)背後的原則,因爲你不能有超過一個關鍵值具有相同的名稱。

如果你想要多個鍵的同名,那麼這些鍵必須包含在一個數組中,這非常類似於你的結構類型和結果。除了對數組元素進行排序,然後將它們組合回數組之外,結果並沒有真正做到。

所以給你一點餘量這裏您只是做了複製粘貼來表示你想要的結果,而你真正想要某種形式的合併內的元素,你總是可以這樣做這樣的:

db.test.aggregate([ 
    { "$unwind": "$Data" }, 
    { "$unwind": "$Data.description.things" }, 
    { "$group": { 
     "_id": "$Data.name", 
     "city": { "$first": "$Data.city" }, 
     "things": { "$addToSet": "$Data.description.things" } 
    }} 
]) 

其產生的結果是:

{ 
    "_id" : "abc", 
    "city" : "Paris", 
    "things" : [ 
     { 
      "fruit" : { 
       "fruit_name" : "cherry", 
       "fruit_rate" : "3 USD" 
      }, 
      "flower" : { 
       "flower_name" : "orchid", 
       "flower_rate" : "2 USD" 
      } 
     }, 
     { 
      "fruit" : { 
       "fruit_name" : "apple", 
       "fruit_rate" : "4 USD" 
      }, 
      "flower" : { 
       "flower_name" : "rose", 
       "flower_rate" : "2 USD" 
      } 
     } 
    ] 
} 

所以具有內在的 「東西」,現在 「推」 連成一個單一的AR同時在一個普通元素上分組並添加一些額外的字段。

如果你真的想要的東西與甚至更​​多的「融合」,甚至可能避免刪除重複的「設置」項,則可以進一步重新塑造有這樣的語句:

db.test.aggregate([ 
    { "$unwind": "$Data" }, 
    { "$unwind": "$Data.description.things" }, 
    { "$project": { 
     "name": "$Data.name", 
     "city": "$Data.city", 
     "things": "$Data.description.things", 
     "type": { "$literal": [ "flower", "fruit" ] } 
    }}, 
    { "$unwind": "$type" }, 
    { "$group": { 
     "_id": "$name", 
     "city": { "$first": "$city" }, 
     "things": { "$push": { "$cond": [ 
      { "$eq": [ "$type", "flower" ] }, 
      { 
       "type": "$type", 
       "name": "$things.flower.flower_name", 
       "rate": "$things.flower.flower_rate" 
      }, 
      { 
       "type": "$type", 
       "name": "$things.fruit.fruit_name", 
       "rate": "$things.fruit.fruit_rate" 
      }, 
     ]}} 
    }} 
]) 

哪給出了結果:

{ 
    "_id" : "abc", 
    "city" : "Paris", 
    "things" : [ 
     { 
      "type" : "flower", 
      "name" : "rose", 
      "rate" : "2 USD" 
     }, 
     { 
      "type" : "fruit", 
      "name" : "apple", 
      "rate" : "4 USD" 
     }, 
     { 
      "type" : "flower", 
      "name" : "orchid", 
      "rate" : "2 USD" 
     }, 
     { 
      "type" : "fruit", 
      "name" : "cherry", 
      "rate" : "3 USD" 
     } 
    ] 
} 

這將甚至可能表明你的原始數據怎麼會在第一時間結構更好。當然,如果你想做這樣的東西,你肯定會需要重塑形狀。「找到'櫻桃','鮮花'或'水果'」或任何類型的總價值。

所以你的結構化的方式,不可能的,你打破上述規則。在我提交的表格中,有幾種方法可以做到這一點。

PS:我今天特意從$sort表示避而遠之,好像它「之類的」在你最初的例子爲你的工作,不要指望這在更廣泛的例子作爲您的值是一個字符串,不是一個數字。簡而言之,這意味着"10 USD"實際上是小於"4 USD"因爲這是如何字符串進行詞彙比較。即:4大於1,這是進行比較的順序。

所以通過拆分的田地,使用數值類型,如更改這些:

 { 
      "type" : "fruit", 
      "name" : "cherry", 
      "rate" : 3, 
      "currency": "USD" 
     } 

你甚至可以對「貨幣」過濾如果這是必需的。

P.P.S$literal運算符是一個可用於MongoDB 2.6及更高版本的構造。在以前的版本,其中該運營商不可用,可以改爲代碼,像這樣:

  "type": { "$cond": [ 1, [ "flower", "fruit" ], 0 ] } 

其中隱晦確實是從$cond(甚至false值)返回true值同樣的事情「字面意思是」宣,所以你放在那裏的東西實際上會被製作出來。在這種情況下,這是一種向投影添加「數組」的方法,這是爲了匹配「類型」而需要的。

您可能會發現在使用$const用於此目的的網引用,但我不是特別相信,因爲儘管它確實存在,它的目的不是爲了這個目的,因此是沒有正式記錄

+0

It Works as hoped!非常感謝! – Mayuri