2017-02-09 11 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 
} 

は、私は1株あたりの収集、およびコレクションごとこれらの文書の何百も、別の日付でそれぞれを持っていると言います。

文字列として書式設定のユーザー用品二つの日付(YYYY-MM-DD)場合:

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

は、どのように私は(、 "START_DATE" と "END_DATE" の間の日付を持つすべてのファイルを取得するにはMongoを照会することができます包括的)?

注:私は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-最初の部分を手助けした日付ストリングをc11-stdchrono-time-point-or-similarと呼ぶ)の投稿。しかし、UTCの時間を考慮していないため、クエリが機能していなかったので、それを指摘してくれてありがとう! – tmalt