MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Kết nối chuỗi theo nhóm

Bạn có thể làm điều đó với khung tổng hợp như một thao tác "hai bước". Đầu tiên là tích lũy các mục vào một mảng thông qua $push withing a $group và sau đó sử dụng $concat với $reduce trên mảng được tạo trong phép chiếu cuối cùng:

db.collection.aggregate([
  { "$group": {
    "_id": "$tag_id",
    "client_id": { "$push": "$client_id" }
  }},
  { "$addFields": {
    "client_id": {
      "$reduce": {
        "input": "$client_id",
        "initialValue": "",
        "in": {
          "$cond": {
            "if": { "$eq": [ "$$value", "" ] },
            "then": "$$this",
            "else": {
              "$concat": ["$$value", ",", "$$this"]
            }
          }
        }
      }
    }
  }}
])

Chúng tôi cũng áp dụng $cond ở đây để tránh nối một chuỗi trống với dấu phẩy trong kết quả, vì vậy nó trông giống một danh sách được phân tách hơn.

FYI Có sự cố với JIRA SERVER-29339 yêu cầu $reduce được triển khai dưới dạng biểu thức tích lũy để cho phép nó sử dụng trực tiếp trong một $group giai đoạn đường ống. Không có khả năng xảy ra sớm, nhưng về mặt lý thuyết, nó sẽ thay thế $push ở trên và làm cho hoạt động trở thành một giai đoạn đường ống duy nhất. Cú pháp đề xuất mẫu về vấn đề JIRA.

Nếu bạn không có $reduce (yêu cầu MongoDB 3.4) sau đó chỉ cần đăng quá trình con trỏ:

db.collection.aggregate([
  { "$group": {
    "_id": "$tag_id",
    "client_id": { "$push": "$client_id" }
  }},
]).map( doc =>
  Object.assign(
    doc,
   { "client_id": doc.client_id.join(",") }
  )
)

Sau đó, dẫn đến cách thay thế khác là thực hiện việc này bằng cách sử dụng mapReduce nếu bạn thực sự phải:

db.collection.mapReduce(
  function() {
    emit(this.tag_id,this.client_id);
  },
  function(key,values) {
    return [].concat.apply([],values.map(v => v.split(","))).join(",");
  },
  { "out": { "inline": 1 } }
)

Tất nhiên, kết quả đầu ra trong mapReduce cụ thể dạng _id và giá trị value như một tập hợp các khóa, nhưng về cơ bản nó là đầu ra.

Chúng tôi sử dụng [].concat.apply([],values.map(...)) bởi vì đầu ra của "bộ giảm" có thể là "chuỗi được phân tách" vì mapReduce hoạt động tăng dần với kết quả lớn và do đó đầu ra của bộ giảm tốc có thể trở thành "đầu vào" trên một đường chuyền khác. Vì vậy, chúng ta cần mong đợi rằng điều này có thể xảy ra và xử lý nó cho phù hợp.



  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Không thể cài đặt plugin Grails MongoDB

  2. Làm cách nào để phát hiện xem bộ nối tiếp mongodb đã được đăng ký chưa?

  3. Meteor và DBRefs

  4. $ elemMatch và cập nhật

  5. MongoDB:Làm cách nào để xuất đúng bộ sưu tập từ MongoDB sang máy tính của tôi?