Dispongo di una libreria molto grande in un ambiente SharePoint Online:> 3000 (set di documenti) nella cartella principale e più di 7000 (set di documenti, cartelle e documenti) in totale. Il sistema si basa principalmente su codice personalizzato: C # CSOM.
Dal punto di vista delle prestazioni, il sistema trarrebbe grandi vantaggi dallinterrogare su sottoinsiemi dellintero set di dati, piuttosto sullintero 7000 elementi ogni volta (la mia soluzione attuale carica lotti di 5000 elementi in un ListItemCollection: nel mio caso prima 5000 e poi 2000, quindi la query viene eseguita da LINQ) soprattutto tenendo presente che alcune operazioni sono direttamente legate a viste specifiche.
Sto provando la seguente implementazione come trovata in un commento su un altro thread .
Microsoft.SharePoint.Client.List list = ctx.Web.Lists.GetByTitle(ListName); ctx.Load(list); ctx.ExecuteQuery(); Microsoft.SharePoint.Client.View view = list.Views.GetByTitle(viewName); ctx.Load(view); ctx.ExecuteQuery(); CamlQuery query = new CamlQuery(); query.ViewXml = view.ViewQuery; ListItemCollection items = list.GetItems(query); ctx.Load(items); ctx.ExecuteQuery();
Il mio problema è che ListItemCollection viene popolato con tutti gli elementi sulla raccolta radice (3000), quando le viste scelte provate consistono al massimo di 60 elementi.
Il view.ViewQuery è popolato con questo valore:
"<GroupBy Collapse=\"FALSE\" GroupLimit=\"30\"><FieldRef Name=\"CurrentStatus\" /></GroupBy><OrderBy><FieldRef Name=\"CurrentStatus\" Ascending=\"FALSE\" /><FieldRef Name=\"Stage\" /></OrderBy><Where><And><Eq><FieldRef Name=\"Stage\" /><Value Type=\"Text\">Confirm Container</Value></Eq><Eq><FieldRef Name=\"PastTransition\" /><Value Type=\"Boolean\">0</Value></Eq></And></Where>"
Il codice sopra dovrebbe funzionare? Se sì, cosa cè che non va? In caso contrario, qual è unaltra soluzione che ottiene lo stesso risultato?
Commenti
- Che aspetto ha ViewQuery come?
Risposta
Stai estraendo CAML dalla vista perché gli utenti potrebbero aggiornare i dettagli del filtro? In caso contrario, il modo migliore per procedere è probabilmente eseguire manualmente la query.
Prova:
query.ViewXml ="<View Scope=\"Recursive\"><Query><Where><And><Eq><FieldRef Name=\"Stage\" /><Value Type=\"Text\">Confirm Container</Value></Eq><Eq><FieldRef Name=\"PastTransition\" /><Value Type=\"Boolean\">0</Value></Eq></And></Where></Query></View>"
Poiché il tuo elenco è> 7k elementi, dovresti anche assicurarti che uno o entrambi delle colonne Stage e PastTransition vengono indicizzate. Potrebbe dipendere da quale restituisce il sottoinsieme di dati più piccolo e in quale ordine vengono valutati.
Potrebbe anche essere necessario eseguire “RecursiveAll” invece di “Recursive”, a seconda se si desidera / è necessario restituire le cartelle. Visualizza lenumerazione dellambito: https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spviewscope.aspx
In questo modo dovresti ottenere lelenco filtrato. Da lì, il tuo codice può fare qualsiasi raggruppamento / ordine sugli articoli restituiti.
Aggiorna
Poiché i dettagli della query devono essere estratti dinamicamente dalle viste esistenti (in base al tuo feedback di seguito), puoi estrarre il contenuto della vista esistente.ViewQuery e iniettarlo nella vista XML sopra. Ciò eliminerà e consentirà anche lesecuzione della query su elenchi> 5k.
Vedi il codice di Jurgen per una soluzione completa.
Commenti
- Funziona così. Significa che limpostazione di una query CAML e il filtro sulle colonne indicizzate con un set di dati interrogabile di più di 5000 elementi, non si arresta in modo anomalo se il risultato restituito è inferiore a 5000? Si tratta di un aggiramento ma non di una soluzione. Non cè modo di ottenere dalla vista? Vorrei che la query fosse creata dinamicamente da più viste e non dovessi ricreare la configurazione della vista nella query CAML ogni volta, se possibile, ovviamente. Questo è già un ottimo inizio però! Quindi grazie molto 🙂
- @JurgenCuschieri: Dovrebbe funzionare bene se ci sono più di 5.000 voci dellelenco. Non sono sicuro di ' di comprendere appieno il tuo caso duso, ma se desideri estrarre dinamicamente i dettagli del filtro dalla vista (o dalle viste), potresti farlo copiando la < Query > porzione di vista ' s CAML e iniettandolo dinamicamente in < View Scrope = " Recusive " > < / Visualizza >.
- ' ci proverò e tornerò da te. Per renderlo un po più chiaro, ho installato un sistema con molte domande diverse. La query CAML viene utilizzata per caricare batch di 5000 articoli in una raccolta di voci di elenco. LINQ viene utilizzato per eseguire query sul ListItemCollection risultante. Inutile dire che loperazione richiede molto tempo per restituire un risultato. Ogni (o quasi) scenario è teoricamente legato a una vista. il che significa che il set di dati interrogabile può essere ridotto a icona per gli stessi risultati di visualizzazione. quindi se la query caml può essere popolata automaticamente dalla visualizzazione ' s query automaticamente – ha più senso, no?
- le viste definiscono fasi particolari allinterno di unazienda cliente processo aziendale di '. quelle operazioni di query CAML utilizzate specificamente allinterno di uno stage possono quindi utilizzare la stessa query della vista. Questo perfezionerà il set di dati interrogabile, invece di utilizzare ogni volta tutti gli elementi nellelenco
- Ottimo! Sono contento che abbia funzionato. Noi sviluppatori di SharePoint dobbiamo restare uniti … 🙂
Answer
La seguente è la mia soluzione finale, basato sulla risposta di @Jim Barntish “.
Microsoft.SharePoint.Client.List list = ctx.Web.Lists.GetByTitle(ListName); ctx.Load(list); ctx.ExecuteQuery(); Microsoft.SharePoint.Client.View view = list.Views.GetByTitle(viewName); ctx.Load(view); ctx.ExecuteQuery(); CamlQuery query = new CamlQuery(); query.ViewXml = view.ViewQuery; int pFrom = query.ViewXml.IndexOf("<Where>") + "<Where>".Length; int pTo = query.ViewXml.LastIndexOf("</Where>"); string whereClause = query.ViewXml.Substring(pFrom, pTo - pFrom); string queryStr = "<View Scope=\"Recursive\"><Query><Where>" + whereClause + "</Where></Query></View>"; query.ViewXml = queryStr; ListItemCollection items = list.GetItems(query); ctx.Load(items); ctx.ExecuteQuery();