1

У меня есть некоторые документы в MongoDB, такие как:Как получить значение примерно от ключа в mapReduce mongoose?

{ 
     "_id" : ObjectId("587f41ffb5ffa43ec25aa075"), 
     "IP" : "113.183.149.127", 
     "Product_Version" : "CMC_2.0", 
     "Product_ID" : "HHFFHJRLAUHOZDBM1YWY291NM0DD7J40", 
     "OS" : "Microsoft_Window_7", 
     "virus" : "Adware:W32/Superfish", 
     "Time" : ISODate("2017-01-18T10:22:55.356Z"), 
     "city_name" : "", 
     "location" : { 
      "latitude" : 0.0, 
      "longitude" : 0.0 
     } 
    } 
    { 
     "_id" : ObjectId("587f41ffb5ffa43ec25aa078"), 
     "IP" : "27.76.109.254", 
     "Product_Version" : "CMC_2.0", 
     "Product_ID" : "UCOV8JY5YHKQ2B0HPCC0IM1S9T0ICWL7", 
     "OS" : "Microsoft_Window_7", 
     "virus" : "Backdoor:W32/BlackEnergy", 
     "Time" : ISODate("2017-01-18T10:22:55.380Z"), 
     "city_name" : "Ho Chi Minh City", 
     "location" : { 
      "latitude" : 10.75, 
      "longitude" : 106.66667 
     } 
    } 
    { 
     "_id" : ObjectId("587f41ffb5ffa43ec25aa079"), 
     "IP" : "42.116.189.121", 
     "Product_Version" : "CMC_2.0", 
     "Product_ID" : "3WKR7313ONV21OXNX1ZGDKG0A0CB89MH", 
     "OS" : "Microsoft_Window_7", 
     "virus" : "Trojan:W97M/MaliciousMacro", 
     "Time" : ISODate("2017-01-18T10:22:55.440Z"), 
     "city_name" : "Hanoi", 
     "location" : { 
      "latitude" : 21.0245, 
      "longitude" : 105.84117 
     } 
    } 

Я использую MapReduce, чтобы найти все документы на дату ("2017-01-18")

var query = {}; 
query.map = function() { 
    var key = new Date("2017-01-18"); 
    var value = { 
     lat: this.location.latitude, 
     lng: this.location.longitude, 
    }; 

    emit(key, value); 
}; 
query.reduce = function(key, values) { 
    var reducedObject = {}; 

    values.forEach(function(value) { 
     reducedObject.lat = value.lat; 
     reducedObject.lng = value.lng; 
    }); 

    return reducedObject; 
}; 
query.out = { 
    replace: "map_reduce" 
}; 
query.verbose = true; 

Msg.mapReduce(query, function(error, model, stats) { 
    if (error) { 
     require(path.join(__dirname, '../', 'ultis/logger.js'))().log('error', JSON.stringify(error)); 
     if (typeof callback === 'function') return callback(-2, null); 
    } else { 
     console.log('map reduce took %d ms', stats.processtime) 

     model.find().exec(function(error, docs) { 
      if (error) { 
       require(path.join(__dirname, '../', 'ultis/logger.js'))().log('error', JSON.stringify(error)); 
       if (typeof callback === 'function') return callback(-2, null); 
      } else { 
       // if (typeof callback === 'function') return callback(null, docs); 
       console.log(docs); 
      } 
     }); 
    } 
}); 

я просто результат, такие как

map reduce took 855 ms 
[ { _id: Wed Jan 18 2017 07:00:00 GMT+0700 (SE Asia Standard Time), 
    value: { lat: 0, lng: 0 } } ] 

I хочу иметь все документы на дату 2017-01-18.

Вопрос 1: Как получить все документы на дату 2017-01-18?

Вопрос 2: Может ли mapReduce получить значение с ключом? Я имею в виду, что я могу получить документы с даты 2017-01-18 до 2017-01-23. Изображение таких как

query.map = function() { 
    var key = {}; 
     key.from = new Date("2017-01-18"); 
     key.to= new Date("2017-01-23"); 
    var value = { 
     lat: this.location.latitude, 
     lng: this.location.longitude, 
    }; 

    emit(key, value); 
}; 

ответ

1

MapReduce является излишеством для этой задачи. Вам нужно только построить запрос диапазона дат, который с этого начала 2017-01-18 00:00hrs до 2017-01-18 23:59:59.999, а затем использовать его в запросе трубопроводном find() или aggregate() :

var start = new Date("2017-01-18"); 
start.setHours(0,0,0,0); 

var end = new Date("2017-01-18"); 
end.setHours(23,59,59,999); 

var query = { "Time": { "$gte": start, "$lte": end } }; 

Msg.find(query, function(error, docs) { 
    if (error) { 
     console.log(error); 
    } else { 
     console.log(docs); 
    } 
}); 

или с использованием aggregate()

Msg.aggregate() 
    .match(query) 
    .exec(function(error, docs) { 
     if (error) { 
      console.log(error); 
     } else { 
      console.log(docs); 
     } 
    }); 

Для ваш второй вопрос - это вопрос изменения диапазона дат запроса до

var start = new Date("2017-01-18"); 
var end = new Date("2017-01-23"); 

var query = { "Time": { "$gte": start, "$lte": end } }; 
+0

Раньше я использовал 'find()' запрос раньше, но это не производительность. У меня около 5 миллионов документов, и этот запрос прерывается из-за таймаута в ответ слишком долго. Если mapReduce не может использовать в случае, я надеюсь, что 'aggregate()' будет работать, чем 'find()'. Спасибо за ваш ответ! – Loint