Mit einer leichten Drehung auf @capaj's post. Hier ist eine allgemeine Möglichkeit, alle Dokument-IDs als eine Liste von Zeichenfolgen zu erhalten. Beachten Sie die Verwendung von Advanced.LuceneQuery<T>(idPropertyName)
, und GetProperty(idPropertyName)
, um Dinge generisch zu machen. Der Standard geht davon aus, dass "Id"
eine gültige Eigenschaft auf dem gegebenen <T>
ist (was in 99,999% der Fälle der Fall sein sollte). Für den Fall, dass Sie eine andere Eigenschaft als Ihre Id
haben, können Sie es auch übergeben.
public static List<string> getAllIds<T>(DocumentStore docDB, string idPropertyName = "Id") {
return getAllIdsFrom<T>(0, new List<string>(), docDB, idPropertyName);
}
public static List<string> getAllIdsFrom<T>(int startFrom, List<string> list, DocumentStore docDB, string idPropertyName) {
var allUsers = list;
using (var session = docDB.OpenSession())
{
int queryCount = 0;
int start = startFrom;
while (true)
{
var current = session.Advanced.LuceneQuery<T>().Take(1024).Skip(start).SelectFields<T>(idPropertyName).ToList();
queryCount += 1;
if (current.Count == 0)
break;
start += current.Count;
allUsers.AddRange(current.Select(t => (t.GetType().GetProperty(idPropertyName).GetValue(t, null)).ToString()));
if (queryCount >= 28)
{
return getAllIdsFrom<T>(start, allUsers, docDB, idPropertyName);
}
}
}
return allUsers;
}
Ein Beispiel, wo/wie ich das ist, wenn ein PatchRequest
in RavenDB mit der BulkInsert
Sitzung zu machen. In einigen Fällen habe ich vielleicht Hunderttausende von Dokumenten und kann es mir nicht leisten, alle Dokumente im Speicher zu laden, nur um sie erneut für die Patch-Operation zu wiederholen ... also das Laden nur ihrer String-IDs in die Patch
Befehl.
void PatchRavenDocs()
{
var store = new DocumentStore
{
Url = "http://localhost:8080",
DefaultDatabase = "SoMeDaTaBaSeNaMe"
};
store.Initialize();
// >>>here is where I get all the doc IDs for a given type<<<
var allIds = getAllIds<SoMeDoCuMeNtTyPe>(store);
// create a new patch to ADD a new int property to my documents
var patches = new[]{ new PatchRequest { Type = PatchCommandType.Set, Name = "SoMeNeWPrOpeRtY" ,Value = 0 }};
using (var s = store.BulkInsert()){
int cntr = 0;
Console.WriteLine("ID Count " + allIds.Count);
foreach(string id in allIds)
{
// apply the patch to my document
s.DatabaseCommands.Patch(id, patches);
// spit out a record every 2048 rows as a basic sanity check
if ((cntr++ % 2048) == 0)
Console.WriteLine(cntr + " " + id);
}
}
}
Ich hoffe, es hilft. :)
RavenDB aktualisiert Ich sehe, dass oben genannte Lösung funktioniert, weil die Gesamt nicht. der Datensätze ist nahe 4000, so dass keine der Abfragen <30 wäre. Nur neugierig, wie wäre die Art und Weise, ein ähnliches Szenario zu behandeln, in dem Total no of records> 30 * 1024 sind, d.h. wenn sie mehr als sagen 31k zählen? – annantDev
@annantDev Sie können die Anzahl der während der Sitzung gestellten Anfragen verfolgen. Sobald es 30 erreicht hat, verlasse die alte Sitzung, erstelle eine neue Sitzung und lese weiter. –