使用Java Graph SDK查找SharePoint近24小时上传文件及自定义列查询问题
问题背景
需要通过Microsoft Graph API SDK查找SharePoint站点中近24小时上传的文件:
- 最初尝试通过
LastModifiedTime字段筛选,但该字段对应文件本地修改时间,而非上传到SharePoint的时间,无法满足需求。 - 转而计划通过名为
processed的Yes/No类型自定义列实现:查询processed=false的文件,处理后将其设为true避免重复处理,但编写的两段查询代码均未生效。
尝试的无效代码
代码1:基于Drive搜索
String siteId = ""; OffsetDateTime startTime = OffsetDateTime.now().minusHours(24); SiteRequestBuilder site = graphClient.sites(siteid); DriveItemSearchCollectionPage results = site.drive().root() .search( DriveItemSearchParameterSet.newBuilder() .withQ("LastModifiedTime ge "+ startTime) .build() ).buildRequest().get(); for (DriveItem driveItem : results.getCurrentPage()) { System.out.println("----------------> "+driveItem.name); }
代码2:全局搜索
SiteRequestBuilder sitereq = graphClient.sites(siteid); String webUrl = sitereq.buildRequest().get().webUrl; String queryString = String.format("isDocument=true AND processed=false AND path: \"%s\" ", webUrl); LinkedList<SearchRequest> requestsList = new LinkedList<>(); SearchRequest requests = new SearchRequest(); LinkedList<EntityType> entityTypesList = new LinkedList<>(); entityTypesList.add(EntityType.DRIVE_ITEM); requests.entityTypes = entityTypesList; LinkedList<SortProperty> sortProperties = new LinkedList<>(); SortProperty sort = new SortProperty(); sort.name = "LastModifiedTime"; sort.isDescending = false; sortProperties.add(sort); SearchQuery query = new SearchQuery(); query.queryString = queryString; requests.query = query; requests.sortProperties = sortProperties; requests.size = 500; requestsList.add(requests); SearchEntityQueryParameterSet sqp = SearchEntityQueryParameterSet .newBuilder() .withRequests(requestsList) .build(); SearchEntityQueryCollectionRequest searchRequest = graphClient.search().query(sqp).buildRequest(); SearchEntityQueryCollectionPage searchResult = searchRequest.post();
问题分析
代码1问题:
- 日期格式错误:Graph API要求ISO 8601格式日期,直接拼接
OffsetDateTime会导致语法无效。 LastModifiedTime本身不符合需求,且Drive的search方法对自定义列支持有限。
- 日期格式错误:Graph API要求ISO 8601格式日期,直接拼接
代码2问题:
- 自定义列查询语法错误:Yes/No类型列在搜索语法中需用
:false而非=false。 - 范围限定不准确:
path:参数不如site:精准,且未确认自定义列是否开启搜索索引。 - 未处理DriveItem与ListItem的关联:自定义列属于列表项字段,无法直接通过DriveItem更新。
- 自定义列查询语法错误:Yes/No类型列在搜索语法中需用
解决方案
方案一:直接查询文档库列表项(推荐)
文档库本质是SharePoint列表,直接查询列表项可精准筛选自定义列,同时用Created字段获取准确的上传时间。
String siteId = "你的站点ID"; // 获取文档库对应的列表ID Drive drive = graphClient.sites(siteId).drive().buildRequest().get(); String listId = drive.list.id; // 构建ISO 8601格式的24小时前时间 String startTime = OffsetDateTime.now().minusHours(24) .format(DateTimeFormatter.ISO_OFFSET_DATE_TIME); // 查询未处理且近24小时上传的文件 ListItemsCollectionPage items = graphClient.sites(siteId).lists(listId).items() .buildRequest() .filter("processed eq false and Created ge '" + startTime + "'") .select("id, fields/name, fields/processed, fields/Created") .expand("fields") .get(); // 处理并更新文件状态 for (ListItem item : items.getCurrentPage()) { System.out.println("文件名: " + item.fields.get("name")); System.out.println("上传时间: " + item.fields.get("Created")); // 更新processed为true ListItem updateItem = new ListItem(); HashMap<String, Object> fields = new HashMap<>(); fields.put("processed", true); updateItem.fields = fields; graphClient.sites(siteId).lists(listId).items(item.id) .buildRequest() .patch(updateItem); }
注意事项:
- 确认
processed是自定义列的内部名称(可在SharePoint列表设置中查看,显示名称有空格时内部名称会自动调整)。 - 确保应用拥有
Sites.ReadWrite.All或对应站点的列表读写权限。
方案二:修复全局搜索代码
若需跨站点搜索,调整搜索语法并处理字段关联:
String siteId = "你的站点ID"; Site site = graphClient.sites(siteId).buildRequest().get(); String webUrl = site.webUrl; // 修正搜索语法:布尔值用:false,用site限定范围 String queryString = String.format("isDocument:true AND processed:false AND site:\"%s\"", webUrl); LinkedList<SearchRequest> requestsList = new LinkedList<>(); SearchRequest request = new SearchRequest(); LinkedList<EntityType> entityTypesList = new LinkedList<>(); entityTypesList.add(EntityType.DRIVE_ITEM); request.entityTypes = entityTypesList; SearchQuery query = new SearchQuery(); query.queryString = queryString; request.query = query; request.size = 500; requestsList.add(request); SearchEntityQueryParameterSet sqp = SearchEntityQueryParameterSet .newBuilder() .withRequests(requestsList) .build(); SearchEntityQueryCollectionPage searchResult = graphClient.search().query(sqp) .buildRequest() .post(); // 处理搜索结果并更新状态 for (SearchHit hit : searchResult.getCurrentPage()) { DriveItem item = hit.resource.cast(DriveItem.class); System.out.println("文件名: " + item.name); // 获取对应的ListItem以更新自定义列 ListItem listItem = graphClient.sites(siteId).drive().items(item.id).listItem() .buildRequest() .get(); ListItem updateItem = new ListItem(); HashMap<String, Object> fields = new HashMap<>(); fields.put("processed", true); updateItem.fields = fields; graphClient.sites(siteId).lists(listItem.parentReference.id).items(listItem.id) .buildRequest() .patch(updateItem); }
注意事项:
- 需在SharePoint列表设置中开启
processed列的「允许在搜索中使用此列」选项,确保列被索引。
内容的提问来源于stack exchange,提问作者rread
相关产品推荐
相关产品推荐

