Newtonsoft JsonTextWriterを使用していくつかのPOCOを手動でシリアル化し、結果をMongoDB BsonDocumentとして保存しています。C#ドライバを使用してMongoDBの日付フィールドをフィルタリングできません
//
// POCO to store in MongoDB
public class Session
{
public DateTime? StartUTCTimestamp { get; set; }
public DateTime? StartTimestamp { get; set; }
public DateTime? EndTimestamp { get; set; }
public void ToJSON(ref JsonTextWriter writer)
{
Session session = this;
writer.WriteStartObject(); // {
writer.WritePropertyName("StartUTCTimestamp");
writer.WriteValue(session.StartUTCTimestamp);
writer.WritePropertyName("StartTimestamp");
writer.WriteValue(session.StartTimestamp);
writer.WritePropertyName("EndTimestamp");
writer.WriteValue(session.EndTimestamp);
writer.WriteEndObject(); // }
}
}
データをインポートするために使用される試験アプリケーションの方法は、リストの結果を格納する(TelerikのオープンアクセスORMを使用して)SQL Serverデータベースからのすべてのセッションオブジェクトを検索します。私は各セッションをPOCO(上を参照)で定義されたToJSON()メソッドを呼び出し、JsonTextWriterへの参照を渡してシリアル化します。結果のJSON文字列は、C#MongoDBドライバを使用してBsonDocumentにデシリアライズされ、Mongoに保存されます。 (以下の例は、ASP.NET Webフォームページからのもので、アラートボックスのユーザーコントロールです)。
private void LoadData()
{
DateTime startDate = new DateTime(2015,12,31,23,59,59);
var collection = _database.GetCollection<BsonDocument>("sessions");
using (DbContext ctx = new DbContext())
{
List<Session> sessions = ctx.Sessions.Where().ToList();
foreach (Session item in sessions)
{
JsonTextWriter writer = null;
try
{
StringWriter sw = new StringWriter();
writer = new JsonTextWriter(sw);
writer.CloseOutput = true;
item.ToJSON(ref writer);
String json = sw.ToString();
BsonDocument doc = MongoDB.Bson.Serialization.BsonSerializer.Deserialize<BsonDocument>(json);
collection.InsertOne(doc);
this.ucAlertMsg.Show("bg-info", "Completed without exception");
}
catch (Exception ex)
{
while (ex.InnerException != null) { ex = ex.InnerException; }
this.ucAlertMsg.Show("bg-danger", ex.Message);
}
finally
{
writer.Close();
}
}
}
}
これは文書をうまく保存していますが、日付範囲をフィルタリングして文書を効果的にクエリできません。私は、読んだ他のいくつかの記事と記事に基づいて、値が "ISODate()"ではなく文字列として保存されている可能性があると考えています。私はそれが役立っている必要がありますように、私が読んだ記事の一部に応じらしいたTextWriter上の多数の構成を試してみましたが、私のloaddataの()メソッドで
//
// This is what IS saved
{
"_id" : ObjectId("5729128cd9017a248cbe6284"),
"StartUTCTimestamp" : "2015-12-15T23:24:06",
"StartTimestamp" : "2015-12-15T18:24:06",
"EndTimestamp" : "2015-12-15T18:26:59",
}
//
// Is this what I need?
{
"_id" : ObjectId("5729128cd9017a248cbe6284"),
"StartUTCTimestamp" : ISODate("2015-12-15T23:24:06"),
"StartTimestamp" : ISODate("2015-12-15T18:24:06"),
"EndTimestamp" : ISODate("2015-12-15T18:26:59"),
}
...
StringWriter sw = new StringWriter();
writer = new JsonTextWriter(sw);
writer.DateFormatHandling = DateFormatHandling.IsoDateFormat;
writer.CloseOutput = true;
ライターの "DateFormatHanding"設定に "IsoDateFormat"を割り当てると、違いはありません。私も "MicrosoftDateFormat"を試してみましたが、データはまだ文字列として保存されていましたが、形式が異なりました。
実際の質問
は、だから、すべての設定だ...質問は、「どのように私は日付に基づいてMongoDBのドキュメントを検索します」ですか?
MongoDB用のC#ドライバを使用すると、Linqを使用して検索できます。ここで私が使用しているlinqクエリです。
IMongoCollection<Session> collection = database.GetCollection<Session>("sessions");
DateTime startDate = (this.StartDate.HasValue) ? this.StartDate.Value : DateTime.Now.AddDays(-7);
DateTime endDate = (this.EndDate.HasValue) ? this.EndDate.Value : DateTime.Now;
var data = collection.Find<Session>(e => e.StartTimestamp.Value >= startDate && e.StartTimestamp.Value <= endDate).ToList();
JSONはセッションPOCOに直接マッピングされるので、そのタイプ(?)を使用できるはずです。セッションPOCOの他のフィールドを正常にフィルタリングできます。それはちょうど私のフィット感を与えている日付です。
私の実装に何か不安や見落としがあると推測しています。データが文字列として保存されているため、日付(?)と比較できません。
洞察力があれば幸いです。
おかげで、 -G