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

Sản phẩm cacte của C # Mongodb của nhiều tài liệu mảng đối tượng

Bạn có thể thử đường dẫn tổng hợp bên dưới.

Lưu ý mergeObjects toán tử tổng hợp có sẵn trong 3.5.6 + phát hành phát triển sẽ được đưa vào 3.6 sắp tới phát hành.

db.collection.find();
{
 "data" : [
  [
   {
    "movie" : "starwars",
    "showday" : "monday"
   },
   {
    "movie" : "batman",
    "showday" : "thursday"
   },
   {
    "movie" : "sleepless",
    "showday" : "tuesday"
   }
  ],
  [
   {
    "actor" : "angelina",
    "location" : "new york"
   },
   {
    "actor" : "jamie",
    "location" : "california"
   },
   {
    "actor" : "mcavoy",
    "location" : "arizona"
   }
  ]
 ]
}

Tổng hợp bằng cách sử dụng biểu thức điều kiện.

aggregate({
 $project: {
  cp: {
   $reduce: {
    input: "$data",
    initialValue: {
     $arrayElemAt: ["$data", 0] // Set the initial value to the first element of the arrays.
    },
    in: {
     $let: {
      vars: {
       currentr: "$$this", // Current processing element
       currenta: "$$value" // Current accumulated value 
      },
      in: {
       $cond: [{ // Conditional expression to return the accumulated value as initial value for first element
        $eq: ["$$currentr", "$$currenta"]
       },
       "$$currenta",
       { // From second element onwards prepare the cartesian product
        $reduce: {
         input: {
          $map: {
           input: "$$currenta",
           as: a"a",
           in: {
            $map: {
             input: "$$currentr",
             as: r"r",
             in: {
              $mergeObjects: ["$$a", "$$r"] // Merge accumulated value with the current processing element
             }
            }
           }
          }
         },
         initialValue: [],
         in: {
         $concatArrays: ["$$value", "$$this"] // Reduce the merged values which will be used as accumulator for next element
         }
        }
       }]
      }
     }
    }
   }
  }
 }
});

Tổng hợp (sử dụng $setUnion ).

Giải pháp này chỉ được thêm vào để loại bỏ biểu thức điều kiện để cung cấp nhiều đường dẫn dễ đọc hơn.

aggregate({
 $project: {
  cp: {
   $reduce: {
    input: "$data",
    initialValue: {
     $arrayElemAt: ["$data", 0] // Set the initial value to the first element of the arrays.
    },
    in: {
     $let: {
      vars: {
       currentr: "$$this", // Current processing element
       currenta: "$$value" // Current accumulated value 
      },
      in:{ 
       $reduce: {
        input: {
         $map: {
          input: "$$currenta",
          as: "a",
          in: {
           $map: {
            input: "$$currentr",
            as: "r",
            in: {
             $mergeObjects: ["$$a", "$$r"] // Merge accumulated value with the current processing element
            }
           }
          }
         }
        },
        initialValue: [],
        in: {
         $setUnion: ["$$value", "$$this"] // Reduce the merged values which will be used as accumulator for next element
        }
       }
      }
     }
    }
   }
  }
 }
});

Cập nhật

Cả hai giải pháp trên sẽ không hoạt động với các giá trị lặp lại trên các mảng như nhận xét của Asya Kamsky bên dưới vì $cond không chính xác trong giải pháp đầu tiên và $setUnion trong giải pháp thứ hai.

Cách khắc phục chính xác là

bắt đầu bằng initialValue trong tổng số [ { } ]

Hoặc

thay đổi đầu vào input để loại trừ phần tử đầu tiên như input: {$slice:["$data", 1, {$subtract:[{$size:"$data"},1]}]},

Hoàn thành đường ống tổng hợp

aggregate({
 $project: {
  cp: {
   $reduce: {
    input: {$slice:["$data", 1, {$subtract:[{$size:"$data"},1]}]},
    initialValue: {$arrayElemAt:["$data",0]},
    in: {
     $let: {
      vars: {
       currentr: "$$this", 
       currenta: "$$value" 
      },
      in:{ 
       $reduce: {
        input: {
         $map: {
          input: "$$currenta",
          as: "a",
          in: {
           $map: {
            input: "$$currentr",
            as: "r",
            in: {
             $mergeObjects: ["$$a", "$$r"] 
            }
           }
          }
         }
        },
        initialValue: [],
        in: {
         $concatArrays: ["$$value", "$$this"] 
        }
       }
      }
     }
    }
   }
  }
 }
});

Tham khảo: Tích Descartes của nhiều mảng trong JavaScript




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Gọi lại lưu của Mongoose hoạt động như thế nào?

  2. Đặt cơ sở dữ liệu mặc định cho MongoDB shell

  3. Truy vấn lồng trong mongoDB

  4. Làm cách nào để hạn chế người dùng mongo bỏ bộ sưu tập?

  5. Cách xóa phần tử thứ n của mảng trong mongodb