Requête CAML sur la vue SharePoint Online

Jai une très grande bibliothèque dans un environnement SharePoint Online:> 3000 (ensembles de documents) dans le dossier racine et plus de 7000 (ensembles de documents, dossiers et documents) au total. Le système est principalement basé sur un code personnalisé: C # CSOM.

En termes de performances, le système bénéficierait grandement de linterrogation sur des sous-ensembles de lensemble de données, plutôt sur lensemble de 7000 éléments à chaque fois (ma solution actuelle charge des lots de 5000 éléments dans une ListItemCollection: dans mon cas dabord 5000 puis 2000, puis linterrogation est effectuée par LINQ), en particulier en gardant à lesprit que certaines opérations sont directement liées à des vues spécifiques.

Jessaye limplémentation ci-dessous, telle quelle se trouve dans un commentaire sur un autre 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(); 

Mon problème est que la ListItemCollection est remplie avec tous les éléments de la collection racine (3000), lorsque les vues choisies essayées comprennent au plus 60 éléments.

La vue.ViewQuery contient cette valeur:

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

Le code ci-dessus est-il censé fonctionner? Si oui, quest-ce qui ne va pas? Sinon, quelle est une autre solution qui permet dobtenir la même chose?

Commentaires

  • À quoi ressemble la requête ViewQuery comme?

Réponse

Tirez-vous CAML de la vue car les utilisateurs pourraient mettre à jour les détails du filtre? Sinon, lancer la requête manuellement est probablement la meilleure façon de procéder.

Essayez ceci:

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

Étant donné que votre liste comprend> 7 000 éléments, vous devez également vous assurer que lun ou les deux des colonnes Stage et PastTransition sont indexées. Cela peut dépendre de celui qui renvoie le plus petit sous-ensemble de données et dans quel ordre ils sont évalués.

Vous devrez peut-être aussi faire « RecursiveAll » au lieu de « Recursive », selon que vous voulez / devez retourner des dossiers. Voir lénumération de létendue: https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spviewscope.aspx

Cela devrait vous donner la liste filtrée. À partir de là, votre code peut effectuer nimporte quel regroupement / commande sur les articles retournés.

Mise à jour

Étant donné que les détails de la requête doivent être extraits dynamiquement des vues existantes (selon vos commentaires ci-dessous), vous pouvez extraire le contenu de la vue existante. dans la vue XML ci-dessus. Cela supprimera et permettra également à la requête de sexécuter sur des listes> 5k.

Voir le code de Jurgen pour une solution complète.

Commentaires

  • Cela fonctionne comme ça. Cela signifie-t-il que la configuration dune requête CAML et le filtrage sur les colonnes indexées avec un ensemble de données interrogeable de plus de 5 000 éléments ne planteront pas si le résultat renvoyé est inférieur à 5 000? Il sagit dun contournement, mais pas réellement dune solution. Je voudrais que la requête soit créée dynamiquement à partir de plusieurs vues et ne pas avoir à recréer la configuration de la vue dans la requête CAML à chaque fois, si cela est possible, bien sûr. Cest déjà un très bon début! Alors merci beaucoup 🙂
  • @JurgenCuschieri: Cela devrait fonctionner correctement sil y a plus de 5K éléments de liste. Je ne suis pas sûr que ' comprenne parfaitement votre cas dutilisation, mais si vous souhaitez extraire dynamiquement les détails du filtre de la ou des vues, vous pouvez probablement le faire en extrayant la < Requête > partie de la vue ' s CAML et linjection dynamique dans < View Scrope = " Recusif " > < / View >.
  • Je ' vais essayer et revenir vers vous. Pour rendre les choses un peu plus claires, jai un système en place avec beaucoup de requêtes différentes. La requête CAML est utilisée pour charger des lots de 5000 éléments dans une collection déléments de liste. LINQ est utilisé pour interroger le ListItemCollection résultant. Inutile de dire que lopération prend beaucoup de temps pour renvoyer un résultat. Chaque scénario (ou presque) est théoriquement lié à une vue. ce qui signifie que lensemble de données interrogeable peut être réduit aux mêmes résultats de vue. donc si la requête caml peut être automatiquement remplie à partir de la requête de la vue ' – cela a plus de sens, non?
  • les vues définissent des étapes particulières au sein dune entreprise cliente Processus métier de '. les opérations de requête CAML qui sont utilisées spécifiquement dans une étape peuvent donc utiliser la même requête que la vue. Cela affinera lensemble de données interrogeable, plutôt que dutiliser tous les éléments de la liste à chaque fois
  • Génial! Heureux que cela ait fonctionné. Nous, les développeurs SharePoint, devons rester ensemble … 🙂

Réponse

Voici ma solution finale, basé sur la réponse de @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(); 

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *