Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> MongoDB

Truy vấn MongoDB lấy giá trị ngẫu nhiên với Map Reduce

Để lấy document ngẫu nhiên, sử dụng mapReduce() kết hợp Math.random() trong hàm map.

Tạo collection 8 document

> db.demo651.insertOne({Value:10});
> db.demo651.insertOne({Value:20});
> db.demo651.insertOne({Value:30});
> db.demo651.insertOne({Value:40});
> db.demo651.insertOne({Value:50});
> db.demo651.insertOne({Value:60});
> db.demo651.insertOne({Value:70});
> db.demo651.insertOne({Value:80});

Hiển thị tất cả

> db.demo651.find();

Kết quả: Value 10,20,30,40,50,60,70,80

MapReduce lấy mẫu ngẫu nhiên (~10%)

> var map = function() {
  if (Math.random() < 0.1) {
    emit(this._id, this);
  }
};
> var reduce = function(key, values) { return values; };
> db.demo651.mapReduce(map, reduce, { out: 'demo_651' });

Kết quả (collection demo_651):

{
  "result": "demo_651",
  "timeMillis": 1104,
  "counts": { "input": 8, "emit": 1, "reduce": 0, "output": 1 },
  "ok": 1
}
> db.demo_651.find();
{ "_id": ObjectId("5e9f033be3c3cd0dcff36a5c"), "value": { "_id": ObjectId("5e9f033be3c3cd0dcff36a5c"), "Value": 60 } }

Giải thích:

  • Math.random() < 0.1: Xác suất 10% mỗi document được emit
  • Kết quả không xác định (random) - chạy lại sẽ ra document khác
  • out: 'demo_651': Ghi kết quả vào collection mới

Cách tốt hơn (MongoDB 3.2+): Dùng $sample trong aggregate:

> db.demo651.aggregate([ { $sample: { size: 1 } } ])
  • Nhanh hơn, không cần tạo collection trung gian
  • Trả về ngẫu nhiên chính xác size document
  • Sử dụng reservoir sampling algorithm

Lưu ý: MapReduce chủ yếu dùng cho xử lý phức tạp, không khuyến nghị cho sampling đơn giản.