CAML-query op SharePoint Online View

Ik heb een zeer grote bibliotheek in een SharePoint Online-omgeving:> 3000 (documentensets) in de hoofdmap en meer dan 7000 (documentsets, folders en documenten) in totaal. Het systeem is voornamelijk gebaseerd op aangepaste code: C # CSOM.

Qua prestaties zou het systeem veel baat hebben bij het zoeken naar subsets van de hele dataset, in plaats van in het algemeen 7000 items elke keer (mijn huidige oplossing laadt batches van 5000 items in een ListItemCollection: in mijn geval eerst 5000 en vervolgens 2000, en vervolgens wordt het doorzoeken gedaan door LINQ), vooral rekening houdend met het feit dat bepaalde bewerkingen rechtstreeks verband houden met specifieke weergaven.

Ik probeer de onderstaande implementatie zoals gevonden in een opmerking op een andere 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(); 

Mijn probleem is dat de ListItemCollection wordt gevuld met alle items in de rootcollectie (3000), terwijl de gekozen weergaven die zijn geprobeerd, maximaal 60 items bevatten.

De view.ViewQuery wordt gevuld met deze waarde:

"<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>" 

Moet de bovenstaande code werken? Zo ja, wat is er mis? Zo niet, wat is dan een andere oplossing waarmee hetzelfde wordt bereikt?

Reacties

  • Hoe ziet de ViewQuery eruit zoals?

Answer

Trek je CAML uit de weergave omdat gebruikers de details van het filter zouden kunnen bijwerken? Als dit niet het geval is, is het waarschijnlijk de beste manier om de zoekopdracht handmatig te starten.

Probeer dit eens:

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>" 

Omdat uw lijst> 7k items is, moet u er ook voor zorgen dat een of beide van de kolommen Stage en PastTransition worden geïndexeerd. Kan afhangen van welke de kleinere subset van gegevens retourneert en in welke volgorde ze worden geëvalueerd.

Mogelijk moet u ook “RecursiveAll” doen in plaats van “Recursive”, afhankelijk van of u mappen wilt / moet retourneren. Bekijk scope-opsomming: https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spviewscope.aspx

Dit zou je de gefilterde lijst moeten opleveren. Van daaruit kan uw code elke groepering / bestelling van de geretourneerde artikelen uitvoeren.

Update

Aangezien querydetails dynamisch uit bestaande views moeten worden gehaald (volgens uw feedback hieronder), kunt u de inhoud van de bestaande view uit de bestaande view halen. ViewQuery en deze injecteren in de view XML hierboven. Hiermee wordt de query verwijderd en kan deze ook worden uitgevoerd op lijsten> 5k.

Zie de code van Jurgen voor een volledig gebakken oplossing.

Opmerkingen

  • Het werkt als volgt. Betekent dit dat het opzetten van een CAML-query en filteren op geïndexeerde kolommen met een doorzoekbare dataset van meer dan 5000 items, crasht niet als het geretourneerde resultaat minder is dan 5000? Dit is een tijdelijke oplossing, maar eigenlijk geen oplossing. Is er geen manier om Ik wil de query dynamisch laten maken vanuit verschillende views en niet elke keer de viewconfiguratie in de CAML-query opnieuw moeten maken, als dat mogelijk is natuurlijk. Dit is echter al een heel goed begin! Dus bedankt veel 🙂
  • @JurgenCuschieri: Het zou goed moeten werken als er meer dan 5K lijstitems zijn. Ik weet niet zeker of ik ' mijn use case volledig begrijp, maar als je de filterdetails dynamisch uit de weergave (of weergaven) wilt halen, zou je dat waarschijnlijk kunnen doen door de < Query > deel van de weergave ' s CAML en het dynamisch injecteren in < View Scrope = " Recusive " > < / Bekijk >.
  • Ik ' zal dat proberen en terug naar jou. Om het wat duidelijker te maken, heb ik een systeem met veel verschillende vragen. CAML-query wordt gebruikt om batches van 5000 items in een lijstitemverzameling te laden. LINQ wordt gebruikt om de resulterende ListItemCollection op te vragen. Het behoeft geen betoog dat de operatie lang duurt voordat een resultaat wordt geretourneerd. Elk (of bijna elk) scenario is theoretisch verbonden met een visie. wat betekent dat de doorzoekbare gegevensset kan worden geminimaliseerd tot dezelfde weergaveresultaten. dus als de caml-query automatisch kan worden ingevuld vanuit de view ' s query automatisch – is logischer, niet?
  • de views definiëren bepaalde fasen binnen een klantbedrijf ' s bedrijfsproces. die CAML-querybewerkingen die specifiek binnen een fase worden gebruikt, kunnen daarom dezelfde query gebruiken als de weergave. Dit zal de doorzoekbare dataset verfijnen, in plaats van alle items in de lijst elke keer te gebruiken.
  • Geweldig! Blij dat het gelukt is. Wij SharePoint-ontwikkelaars moeten bij elkaar blijven … 🙂

Antwoord

Het onderstaande is mijn laatste oplossing, gebaseerd op het antwoord van @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(); 

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *