SharePoint Online 환경에 매우 큰 라이브러리가 있습니다. 루트 폴더에> 3000 (문서 세트), 7000 개 이상 (문서 세트, 폴더 및 문서) 총. 이 시스템은 주로 사용자 지정 코드 인 C # CSOM을 기반으로합니다.
성능면에서 시스템은 매번 전체 7000 개 항목이 아니라 전체 데이터 세트의 하위 집합에 대한 쿼리를 통해 큰 이점을 얻을 수 있습니다 (현재 내 솔루션은 ListItemCollection에 5000 개 항목의 일괄 처리를로드합니다. 특히 특정 작업이 특정 뷰에 직접 연결된다는 점을 염두에두고 LINQ에서 쿼리를 수행합니다.
다른 스레드 에 대한 의견에서 볼 수 있듯이 아래 구현을 시도하고 있습니다.
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();
내 문제는 선택한보기가 최대 60 개 항목으로 구성 될 때 ListItemCollection이 루트 컬렉션 (3000)의 모든 항목으로 채워지고 있다는 것입니다.
view.ViewQuery는 다음 값으로 채워집니다.
"<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>"
위 코드가 작동해야합니까? 그렇다면 무엇이 문제입니까? 그렇지 않은 경우 동일한 작업을 수행하는 또 다른 솔루션은 무엇입니까?
댓글
- ViewQuery는 어떤 모양입니까? 좋아요?
답변
사용자가 필터의 세부 정보를 업데이트 할 수 있기 때문에보기에서 CAML을 가져 오나요? 그렇지 않은 경우 쿼리를 수동으로 채우는 것이 더 나은 방법 일 것입니다.
사용해보세요.
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>"
목록이 7k 개를 초과하는 항목이므로 하나 또는 둘 다 확인해야합니다. Stage 및 PastTransition 열의 색인이 생성됩니다. 더 작은 데이터 하위 집합을 반환하는 데이터와 평가되는 순서에 따라 달라질 수 있습니다.
폴더를 반환할지 여부에 따라 “Recursive”대신 “RecursiveAll”을 수행해야 할 수도 있습니다. 범위 열거보기 : https://msdn.microsoft.com/en-us/library/microsoft.sharepoint.spviewscope.aspx
이렇게하면 필터링 된 목록이 표시됩니다. 여기에서 코드는 반환 된 항목에 대한 그룹화 / 주문을 수행 할 수 있습니다.
업데이트
쿼리 세부 정보를 기존 뷰에서 동적으로 가져와야하므로 (아래 의견에 따라) 기존 뷰에서 콘텐츠를 가져 와서 삽입 할 수 있습니다. 위의보기 XML에. 이렇게하면 쿼리가 5k 이상의 목록에서 실행되고 제거됩니다.
완전히 구워진 솔루션에 대해서는 Jurgen의 코드를 참조하십시오.
댓글
- 이렇게 작동합니다. CAML 쿼리를 설정하고 쿼리 가능한 데이터 세트가 5000 개가 넘는 인덱싱 된 열에서 필터링하면 반환 된 결과가 5000 개 미만인 경우 충돌이 발생하지 않습니까? 이것은 해결 방법이지만 실제로는 해결책이 아닙니다. 가져올 방법이 없습니다. 여러 뷰에서 쿼리를 동적으로 생성하고 가능하면 매번 CAML 쿼리에서 뷰 구성을 다시 만들 필요가 없습니다. 이것은 이미 아주 좋은 시작입니다! 그래서 감사합니다. 많이 🙂
- @JurgenCuschieri : 목록 항목이 5K 이상이면 제대로 작동합니다. 사용 사례를 완전히 이해하고 있는지 ' 확실하지 않지만 뷰 (또는 뷰)에서 동적으로 필터 세부 정보를 가져 오려면 < Query > 뷰의 일부 '의 CAML과이를 < View Scrope = " Recusive > < / View >.
- ' 다시 시도하고 다시 되돌릴 것입니다. 좀 더 명확하게하기 위해 다양한 쿼리가있는 시스템이 있습니다. CAML 쿼리는 5000 개 항목의 일괄 처리를 목록 항목 컬렉션으로로드하는 데 사용됩니다. LINQ는 결과 ListItemCollection을 쿼리하는 데 사용됩니다. 말할 필요도없이 결과를 반환하는 데 시간이 오래 걸립니다. 모든 (또는 거의 모든) 시나리오는 이론적으로보기와 연결되어 있습니다. 이는 쿼리 가능한 데이터 세트를 동일한보기 결과로 최소화 할 수 있음을 의미합니다. 따라서보기에서 자동으로 caml 쿼리를 채울 수 있다면 '의 쿼리를 자동으로 채울 수 있습니다. 더 말이되지 않습니까?
- 보기는 클라이언트 회사 내의 특정 단계를 정의합니다 '의 비즈니스 프로세스. 따라서 스테이지 내에서 특별히 사용되는 CAML 쿼리 작업은 뷰와 동일한 쿼리를 사용할 수 있습니다. 이렇게하면 매번 목록의 모든 항목을 사용하지 않고 쿼리 가능한 데이터 세트를 구체화합니다.
- 좋습니다! 잘됐다 니 다행이다. 우리 SharePoint 개발자들은 함께 뭉쳐야합니다 … 🙂
답변
아래는 저의 최종 솔루션입니다. @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();