Jeg har et meget stort bibliotek i et SharePoint Online-miljø:> 3000 (dokumentsæt) i rodmappen og mere end 7000 (dokumentsæt, mapper og dokumenter) i alt. Systemet er hovedsageligt baseret på brugerdefineret kode: C # CSOM.
Ydelsesmæssigt ville systemet have stor gavn af at forespørge på delmængder af hele datasættet snarere på hele 7000 emner hver gang (min nuværende løsning indlæser batcher på 5000 emner i en ListItemCollection: i mit tilfælde først 5000 og derefter 2000, og derefter foretages forespørgsler af LINQ) især med tanke på, at visse operationer er direkte knyttet til specifikke synspunkter.
Jeg prøver nedenstående implementering som fundet i en kommentar til en anden 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();
Mit problem er, at ListItemCollection befolkes med alle elementerne i rodsamlingen (3000), når de valgte forsøgte visninger består af højst 60 poster.
Visningen.ViewQuery er befolket med denne værdi:
"<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>"
Skal ovenstående kode fungere? Hvis ja, hvad er der galt? Hvis ikke, hvad er der en anden løsning, der opnår den samme ting?
Kommentarer
- Hvad ser ViewQuery ud ligesom?
Svar
Trækker du CAML fra visningen, fordi brugerne muligvis opdaterer detaljerne i filteret? Hvis ikke, er det sandsynligvis den bedste måde at gå på, at manuel opgradering af forespørgslen manuelt.
Prøv dette:
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>"
Fordi din liste er> 7.000 emner, skal du også sørge for, at en eller begge dele i kolonnerne Stage og PastTransition er indekseret. Kan afhænge af, hvilken der returnerer den mindre delmængde af data, og i hvilken rækkefølge de evalueres.
Du skal muligvis også gøre “RecursiveAll” i stedet for “Recursive”, afhængigt af om du vil / har brug for at returnere mapper. Vis optælling af rækkevidde: https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spviewscope.aspx
Dette skulle give dig den filtrerede liste. Derfra kan din kode foretage enhver gruppering / bestilling på de returnerede varer.
Opdatering
Da forespørgselsoplysninger skal pulses dynamisk fra eksisterende visninger (i henhold til din feedback nedenfor), kan du trække indholdet af det ud af den eksisterende visning.ViewQuery og indsprøjte det i XML-visningen ovenfor. Dette slipper af og tillader også forespørgslen at køre på lister> 5k.
Se Jurgens kode for en fuldt bagt løsning.
Kommentarer
- Det fungerer sådan her. Betyder det, at opsætning af en CAML-forespørgsel og filtrering på indekserede kolonner med et datasætt, der kan spørges på mere end 5000 emner, går ikke ned, hvis det returnerede resultat er mindre end 5000? Dette er en løsning, men faktisk ikke en løsning. Er der ingen måde at få det fra visningen? Jeg vil gerne have forespørgslen oprettet dynamisk fra flere visninger og ikke behøver at genskabe visningskonfigurationen i CAML-forespørgsel hver gang, hvis det er naturligvis muligt. Dette er allerede en meget god start! Så tak meget 🙂
- @JurgenCuschieri: Det skal fungere fint, hvis der er mere end 5K listeelementer. Ikke sikker på, at jeg ' fuldt ud forstår din brugssag, men Hvis du vil trække filteroplysningerne ud af visningen (eller visningerne) dynamisk, kan du sandsynligvis gøre det ved at rippe < Forespørgsel > del af udsigten ' s CAML og injicerer det dynamisk i < Vis Scrope = " Recusive " > < / Vis >.
- Jeg ' Jeg prøver det og vender tilbage til dig. For at gøre det lidt klarere har jeg et system på plads med mange forskellige forespørgsler. CAML-forespørgsel bruges til at indlæse batches på 5000 varer i en listeelementsamling. LINQ bruges til at forespørge den resulterende ListItemCollection. Det er overflødigt at sige, at operationen tager lang tid at returnere et resultat. Hvert (eller næsten ethvert) scenario er teoretisk bundet til en visning. hvilket betyder, at det forespørgbare datasæt kan minimeres til de samme visningsresultater. så hvis caml-forespørgslen automatisk kan udfyldes fra visningen ' s forespørgsel automatisk – giver mere mening, nej?
- visningerne definerer bestemte faser inden for et klientfirma ' s forretningsproces. disse CAML-forespørgselshandlinger, der bruges specifikt inden for et trin, kan derfor bruge den samme forespørgsel som visningen. Dette vil finjustere det forespørgselige datasæt i stedet for at bruge alle elementerne på listen hver gang
- Fantastisk! Glad for, at det gik. Us SharePoint-udviklere skal holde sammen … 🙂
Svar
Nedenfor er min endelige løsning, baseret 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();