Ich manuell eine Reihe von POCOs mit Newtonsoft JsonTextWriter serialisieren und das Ergebnis als MongoDB BsonDocument speichern.Kann nicht nach Datumsfeldern in MongoDB mit C# -Treiber filtern
//
// 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(); // }
}
}
Verfahren in einer Testanwendung, die die Daten zu importieren, verwendet wird, ruft alle Session Objekte aus einer SQL Server-Datenbank (unter Verwendung von Open-Access-ORM Telerik) die Ergebnisse in einer Liste speichern. Ich serialisiere jede Sitzung, indem ich die ToJSON() -Methode aufruft, die auf dem POCO definiert ist (siehe oben), und übergebe einen Verweis auf einen JsonTextWriter. Die resultierende JSON-Zeichenfolge wird dann mit dem C# MongoDB-Treiber in ein BsonDocument deserialisiert, das dann in Mongo gespeichert wird. (Das folgende Beispiel stammt von einer ASP.NET Web Forms-Seite, daher die Benutzersteuerelemente des Benachrichtigungsfelds).
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();
}
}
}
}
Dies spart das Dokument ganz gut, aber ich bin nicht in der Lage effektiv die Dokumente abfragen zu, Filterung auf einem Datumsbereich. Ich glaube, basierend auf mehreren anderen Posts und Artikeln, die ich gelesen habe, dass dies möglicherweise daran liegt, dass der Wert als String statt "ISODate()" gespeichert wird.
//
// 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"),
}
In meinem Loaddata() -Methode ich eine Reihe von Konfigurationen auf dem Textwriter versucht haben, die nach einige der Artikel, die ich gelesen haben scheint, wie es geholfen haben sollte ...
StringWriter sw = new StringWriter();
writer = new JsonTextWriter(sw);
writer.DateFormatHandling = DateFormatHandling.IsoDateFormat;
writer.CloseOutput = true;
Das Zuweisen des "IsoDateFormat" zu der "DateFormatHanding" -Einstellung des Brenners ergab keinen Unterschied. Ich habe auch versucht "MicrosoftDateFormat" und die Daten wurden noch als String gespeichert, aber das Format war anders.
Die eigentliche Frage
Also das ist alles eingerichtet ... die Frage „Wie kann ich MongoDB Dokumente nach Datum suchen“?
Mit dem C# -Treiber für MongoDB kann ich mit Linq suchen. Hier ist die Linq-Abfrage, die ich verwende.
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();
Da die JSON-Karten auf eine Session POCO direkt zurück sollte ich diese Art verwenden können (?). Ich kann erfolgreich auf andere Felder in der Sitzung POCO filtern. Es sind nur die Daten, die mir passen.
Ich vermute, dass in meiner Implementierung entweder etwas nicht stimmt oder ein Versehen vorliegt oder dass die Daten, da sie als String gespeichert werden, nicht als Date (?) Verglichen werden können.
Jeder Einblick würde sehr geschätzt werden.
Danke, -G