2013-02-09 33 views
8

Hãy xem xét ví dụ sau:

db.article.aggregate(
    { $group : { 
     _id : "$author", 
     docsPerAuthor : { $sum : 1 }, 
     viewsPerAuthor : { $sum : "$pageViews" } 
    }} 
); 

này nhóm theo lĩnh vực tác giả và tính hai lĩnh vực.

Tôi có giá trị cho $ author = FirstName_LastName. Bây giờ thay vì nhóm theo tác giả $, tôi muốn nhóm bởi tất cả các tác giả chia sẻ cùng một LastName.

tôi đã cố gắng $ regex để nhóm bởi tất cả các chuỗi phù hợp sau khi '_'

$author.match(/_[a-zA-Z0-9]+$/) 

db.article.aggregate(
    { $group : { 
     _id : "$author".match(/_[a-zA-Z0-9]+$/), 
     docsPerAuthor : { $sum : 1 }, 
     viewsPerAuthor : { $sum : "$pageViews" } 
    }} 
); 

also tried the following: 

db.article.aggregate(
    { $group : { 
     _id : {$author: {$regex: /_[a-zA-Z0-9]+$/}}, 
     docsPerAuthor : { $sum : 1 }, 
     viewsPerAuthor : { $sum : "$pageViews" } 
    }} 
); 

Trả lời

6

Trên thực tế không có phương pháp như vậy mà cung cấp loại hình chức năng hoặc tôi không thể tìm thấy phiên bản phù hợp, trong đó có nó. Điều đó sẽ không làm việc với $ regexp tôi nghĩ rằng: http://docs.mongodb.org/manual/reference/operator/regex/ nó chỉ là cho phù hợp với mô hình.

Có một yêu cầu cải thiện trong jira: https://jira.mongodb.org/browse/SERVER-6773

Nó ở trạng thái chưa được giải quyết mở. NHƯNG

trong github tôi tìm thấy disscussion này: https://github.com/mongodb/mongo/pull/336

Và nếu bạn kiểm tra này cam kết: https://github.com/nleite/mongo/commit/2dd175a5acda86aaad61f5eb9dab83ee19915709

nó chứa nhiều hay ít chính xác phương pháp này bạn có thể có. Tôi không thực sự nhận được quan điểm của trạng thái của cải tiến này: trong 2.2.3 nó không hoạt động.

+0

nhờ. tôi sẽ mang nó đến jira.mongodb.org – user1447121

4

Sử dụng bản đồReduce: đó là dạng tổng hợp chung. Đây là cách thức tiến hành trong vỏ Mongo: Xác định chức năng bản đồ

var mapFunction = function() { 
    var key = this.author.match(/_[a-zA-Z0-9]+$/)[0]; 
    var nb_match_bar2 = 0; 
    if(this.bar.match(/bar2/g)){ 
    nb_match_bar2 = 1; 
    } 
    var value = { 
    docsPerAuthor: 1, 
    viewsPerAuthor: Array.sum(this.pageViews) 
    }; 

    emit(key, value); 
}; 

và chức năng

var reduceFunction = function(key, values) { 

    var reducedObject = { 
    _id: key, 
    docsPerAuthor: 0, 
    viewsPerAuthor: 0 
    }; 

    values.forEach(function(value) { 
    reducedObject.docsPerAuthor += value.docsPerAuthor; 
    reducedObject.viewsPerAuthor += value.viewsPerAuthor; 
    } 
); 
    return reducedObject; 
}; 

chạy MapReduce giảm và lưu kết quả trong map_reduce_result

>db.st.mapReduce(mapFunction, reduceFunction, {out:'map_reduce_result'}) 

truy vấn map_reduce_result để có kết quả

>db.map_reduce_result.find() 
3

Cách giải quyết có thể xảy ra với khung tổng hợp bao gồm việc sử dụng $ project để tính toán tên tác giả. Tuy nhiên, nó là bẩn khi bạn cần phải tự vòng qua các kích thước tên đầu tiên khác nhau:

Tại đây, chúng tôi tính toán tên trường dưới dạng chuỗi con sau ký tự '_', cố gắng mỗi vị trí có thể có của nó là một chuỗi của $ cond), và fallbacking trong trả lại toàn bộ $ tác giả nếu tên đầu tiên là quá dài:

http://mongotry.herokuapp.com/#?bookmarkId=52fb5f24a0378802003b4c68

[ 
{ 
    "$project": { 
     "author": 1, 
     "pageViews": 1, 
     "name": { 
      "$cond": [ 
       { 
        "$eq": [ 
         { 
          "$substr": [ 
           "$author", 
           0, 
           1 
          ] 
         }, 
         "_" 
        ] 
       }, 
       { 
        "$substr": [ 
         "$author", 
         1, 
         999 
        ] 
       }, 
       { 
        "$cond": [ 
         { 
          "$eq": [ 
           { 
            "$substr": [ 
             "$author", 
             1, 
             1 
            ] 
           }, 
           "_" 
          ] 
         }, 
         { 
          "$substr": [ 
           "$author", 
           2, 
           999 
          ] 
         }, 
         { 
          "$cond": [ 
           { 
            "$eq": [ 
             { 
              "$substr": [ 
               "$author", 
               2, 
               1 
              ] 
             }, 
             "_" 
            ] 
           }, 
           { 
            "$substr": [ 
             "$author", 
             3, 
             999 
            ] 
           }, 
           { 
            "$cond": [ 
             { 
              "$eq": [ 
               { 
                "$substr": [ 
                 "$author", 
                 3, 
                 1 
                ] 
               }, 
               "_" 
              ] 
             }, 
             { 
              "$substr": [ 
               "$author", 
               4, 
               999 
              ] 
             }, 
             { 
              "$cond": [ 
               { 
                "$eq": [ 
                 { 
                  "$substr": [ 
                   "$author", 
                   4, 
                   1 
                  ] 
                 }, 
                 "_" 
                ] 
               }, 
               { 
                "$substr": [ 
                 "$author", 
                 5, 
                 999 
                ] 
               }, 
               "$author" 
              ] 
             } 
            ] 
           } 
          ] 
         } 
        ] 
       } 
      ] 
     } 
    } 
}, 
{ 
    "$group": { 
     "_id": "$name", 
     "viewsPerAuthor": { 
      "$sum": "$pageViews" 
     } 
    } 
} 
] 
Các vấn đề liên quan