Jag har ett mycket stort bibliotek i en SharePoint Online-miljö:> 3000 (dokumentuppsättningar) i rotmappen och mer än 7000 (dokumentuppsättningar, mappar och dokument) totalt. Systemet är huvudsakligen baserat på anpassad kod: C # CSOM.
Prestationsmässigt skulle systemet ha stor nytta av att fråga efter underuppsättningar av hela datamängden, snarare på hela 7000 artiklar varje gång (min nuvarande lösning laddar satser på 5000 objekt i en ListItemCollection: i mitt fall först 5000 och sedan 2000, och sedan görs frågan av LINQ) särskilt med tanke på att vissa operationer är direkt knutna till specifika vyer.
Jag försöker implementeringen nedan som den finns i en kommentar till en annan tråd .
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();
Mitt problem är att ListItemCollection fylls med alla objekt i rotsamlingen (3000), när de valda vyer som testats består av högst 60 objekt.
View.ViewQuery fylls med det här värdet:
"<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>"
Ska koden ovan fungera? Om ja, vad är fel? Om inte, vad är en annan lösning som uppnår samma sak?
Kommentarer
- Hur ser ViewQuery ut som?
Svar
Dra du CAML från vyn eftersom användare kan uppdatera detaljerna i filtret? Om inte, är det troligtvis det bästa sättet att göra upp frågan manuellt.
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>"
Eftersom din lista är> 7 000 objekt, måste du också se till att en eller båda i kolumnerna Stage och PastTransition indexeras. Kan bero på vilken som returnerar den mindre delmängden av data och i vilken ordning de utvärderas.
Du kan också behöva göra ”RecursiveAll” istället för ”Recursive”, beroende på om du vill / behöver returnera mappar. Visa uppräkning av räckvidd: https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spviewscope.aspx
Detta bör ge dig den filtrerade listan. Därifrån kan din kod göra vilken gruppering / beställning som helst på de returnerade artiklarna.
Uppdatering
Eftersom frågedetaljer måste pulses dynamiskt från befintliga vyer (enligt din feedback nedan) kan du dra innehållet från den befintliga vyn. ViewQuery och injicera det i vyn XML ovan. Detta kommer att bli av med och även låta frågan köras på listor> 5k.
Se Jurgens kod för en helt bakad lösning.
Kommentarer
- Det fungerar så här. Betyder det att ställa in en CAML-fråga och filtrera på indexerade kolumner med en frågabar datauppsättning på mer än 5000 objekt, kommer inte att krascha om det returnerade resultatet är mindre än 5000? det från vyn? Jag skulle vilja att frågan skulle skapas dynamiskt från flera vyer och inte behöva återskapa vykonfigurationen i CAML-frågan varje gång, om det är möjligt, naturligtvis. Det här är dock en mycket bra start! Så tack mycket 🙂
- @JurgenCuschieri: Det ska fungera bra om det finns fler än 5 000 listobjekt. Inte säker på att jag ' förstår fullständigt ditt användningsfall, men om du vill dra ut filterdetaljerna ur vyn (eller vyer) dynamiskt, kan du förmodligen göra det genom att rippa < Frågan > del av vyn ' s CAML och injicerar det dynamiskt i < Visa Scrope = " Recusive " > < / Visa >.
- Jag ' Jag försöker det och återgår till dig. För att göra det lite tydligare har jag ett system på plats med många olika frågor. CAML-förfrågan används för att ladda satser om 5000 objekt i en listobjektsamling. LINQ används för att fråga den resulterande ListItemCollection. Det behöver inte sägas att operationen tar lång tid att returnera ett resultat. Varje (eller nästan varje) scenario är teoretiskt knutet till en vy. vilket innebär att den ifrågasatta datauppsättningen kan minimeras till samma vyresultat. så om caml-frågan automatiskt kan fyllas i från vyn ' s fråga automatiskt – är mer vettigt, nej?
- vyerna definierar specifika steg i ett klientföretag ' s affärsprocess. de CAML-frågefunktioner som används specifikt inom ett steg kan därför använda samma fråga som vyn. Detta kommer att förfina den ifrågasatta datauppsättningen, snarare än att använda alla objekt i listan varje gång
- Bra! Glad att det fungerade. Oss SharePoint-utvecklare måste hålla ihop … 🙂
Svar
Nedan är min slutliga lösning, baserat på @Jim Barntishs svar.
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();