2017-02-09 9 views
1

Используя драйвер mongocxx, мне нужно запросить mongodb для документов (данных запаса), которые попадают в определенный диапазон дат.mongodb: запрос в диапазоне дат

Рассмотрим следующий формат документа:

{ 
    date : ISODate("2010-01-01T00:00:00Z"), 
    open : 12.00, 
    high : 13.00, 
    low : 11.00, 
    close : 12.50, 
    volume : 100000 
} 

Say У меня есть один сбор за акцию, и сотни этих документов в коллекции, каждая из которых имеет другую дату.

Если пользователь поставляет две даты, отформатированные в виде строк (гггг-мм-дд):

std::string start_date = "2010-01-01"; 
std::string end_date = "2010-02-05"; 

Как я могу запросить Монго, чтобы получить все файлы с датами между «датой_начала» и «датой_окончания», (включительно)?

Примечание: Я использую MongoDB 3.2.12, mongocxx версия драйвера 3.0.2

Спасибо,

ответ

0

К сожалению, не похоже, способ разбора даты из строки с произвольными часовых поясов; предполагается, что все синтаксисы дат находятся в локали пользователя, что означает, что вам нужно будет предоставить смещение, чтобы иметь возможность правильно запрашивать даты UTC, хранящиеся в базе данных. В идеале они могут быть сгенерированы, когда пользователь предоставляет строку, но это, очевидно, будет зависеть от характера вашего приложения.

Как только у вас есть смещение и строка даты, std::get_time доставит вам большую часть пути. После этого вам просто нужно преобразовать std::tm в тип, из которого вы можете построить bsoncxx::types::b_date, а затем запросить, как обычно. Вот пример кода, который делает работу:

#include <chrono> 
#include <cstdint> 
#include <ctime> 
#include <iomanip> 
#include <iostream> 
#include <ostream> 
#include <sstream> 
#include <string> 

#include <bsoncxx/builder/basic/document.hpp> 
#include <bsoncxx/builder/basic/kvp.hpp> 
#include <bsoncxx/builder/basic/sub_document.hpp> 
#include <bsoncxx/json.hpp> 
#include <bsoncxx/types.hpp> 
#include <mongocxx/client.hpp> 
#include <mongocxx/uri.hpp> 

bsoncxx::types::b_date read_date(const std::string& date, 
           std::int32_t offset_from_utc) { 
    std::tm utc_tm{}; 
    std::istringstream ss{date}; 

    // Read time into std::tm. 
    ss >> std::get_time(&utc_tm, "%Y-%m-%d"); 

    // Convert std::tm to std::time_t. 
    std::time_t utc_time = std::mktime(&utc_tm); 

    // Convert std::time_t std::chrono::systemclock::time_point. 
    std::chrono::system_clock::time_point time_point = 
     std::chrono::system_clock::from_time_t(utc_time); 

    return bsoncxx::types::b_date{time_point + 
            std::chrono::hours{offset_from_utc}}; 
} 

int main() { 
    // User inputs 

    std::string start_date = "2010-01-01"; 
    std::string end_date = "2010-02-05"; 

    std::int32_t offset_from_utc = -5; 

    // Code to execute query 

    mongocxx::client client{mongocxx::uri{}}; 
    mongocxx::collection coll = client["db_name"]["coll_name"]; 

    bsoncxx::builder::basic::document filter; 
    filter.append(bsoncxx::builder::basic::kvp(
     "date", [start_date, end_date, 
       offset_from_utc](bsoncxx::builder::basic::sub_document sd) { 
      sd.append(bsoncxx::builder::basic::kvp(
       "$gte", read_date(start_date, offset_from_utc))); 
      sd.append(bsoncxx::builder::basic::kvp(
       "$lte", read_date(end_date, offset_from_utc))); 
     })); 

    for (auto&& result : coll.find(filter.view())) { 
     std::cout << bsoncxx::to_json(result) << std::endl; 
    } 
} 
+0

В то время, так как я разместил вопрос, я нашел [это] (http://stackoverflow.com/questions/21021388/how-to-parse-a- date-string-in-a-c11-stdchrono-time-point-or-like), который помог с первой частью. Однако мои запросы не работали, потому что я не учитывал время UTC, поэтому спасибо, что указали это! – tmalt

 Смежные вопросы

  • Нет связанных вопросов^_^