Query SharePoint items with Microsoft Graph and Search

Query SharePoint items with Microsoft Graph and Search

Recently I wrote a blog post about Microsoft Graph and how to query SharePoint items. I showed how to query lists and libraries. What I did not show there but what is meanwhile also available in v1.0 is the option to retrieve items beyond a single list and with Search. Same approach as with the SharePoint Rest Api where you are also able to retrieve items beyond the boundaries of a list or site collection with one single search call.

Content

General things

The endpoint you need to call is

https://graph.microsoft.com/v1.0/search/query

Although you want to retrieve something you need to make a POST call. That is because you need to handover a more or less packed / complex body with several parameters. At least you need an entityType (see below) and a query (see next). You can furthermore make a projection and retrieve specific fields to either omit some of the standard ones or to add additional custom managed properties (also see later).

So lets do a very simple try in the Graph Explorer:

POST to above mentioned endpoint and insert a very simple request body:

{ "requests": [ 
  {
    "entityTypes": [ "listItem" ],
    "query": { "queryString": "*" } 
  } 
]}

The response you get might look similar to the following:

{ "@odata.context": "https://graph.microsoft.com/v1.0/$metadata#Collection(microsoft.graph.searchResponse)", 
  "value": [ { 
    "searchTerms": [], 
    "hitsContainers": [ { 
      "total": 544, 
      "moreResultsAvailable": true, 
      "hits": [ { 
        "hitId": "01PHBAEIQV4R3J2KYQTFFZMKXPHU6IYJGH", 
        "rank": 1, 
        "summary": "", 
        "resource": { 
          "@odata.type": "#microsoft.graph.listItem", 
          "id": "01PHBAEIQV4R3J2KYQTFFZMKXPHU6IYJGH", 
          "createdDateTime": "2021-06-01T06:43:05Z", 
          "lastModifiedDateTime": "2021-06-01T06:43:05Z", 
          "webUrl": "https://mmsharepoint.sharepoint.com/teams/MMTeamNo212/SiteAssets/Forms/DispForm.aspx?ID=2",
          "sharepointIds": { 
              "listId": "63f9eede-c533-...", 
              "listItemId": "2"
          } 
          "createdBy": { "user": { "displayName": "Systemkonto" } }, 
          "lastModifiedBy": { "user": { "displayName": "Systemkonto" } }, 
          "parentReference": { 
            "siteId": "mmsharepoint.sharepoint.com,5b3bbe35-...,c60a39d3-b836-...",
          } 
        } 
      },
     ...

Lots of interesting information is returned per hit. The url of the item, when it was created and modified respectively by whom. Also the parent reference, on the one hand the Graph typical siteId but also the SharePoint Ids which you could use in case you continue with the SharePoint Rest Api (in SPFx for instance …).
But of course that’s not all. Following there will be a deeper look on what can be done / retrieved.

Search Query

Of course a very simple search query like “*” is by far not the only option. All in all you can use the available, well known and documented KQL for SharePoint
Of course only managed properties declared as queryable can be used.

ListItem vs Driveitem

As there is a relationship between ListItem and DriveItem when querying SharePoint items from list/drive it still exists somehow in Search. As you have already seen there is an entityType to be provided with the searchRequest. Those include but are not limited to listItem and driveItem. There is a slight difference what will be returned when a listItem or driveItem is the result. Custom fields always belong to the listItem (even if it’s a library item like a document e.g.) but see next. The parentReference with driveId or typical file info like name or size only belong to the driveItem.

Field selection

To retrieve even more information than in above’s general sample there is a “fields” option in the searchRequest. Use it like this for example:

{ "requests": [ 
{ "entityTypes": [ "listItem" ], 
  "query": { "queryString": "*" }, 
  "fields": [
              "title",
              "ListItemId",
              "ListID",
              "Filename",
              "WebUrl",
              "SiteID",
              "WebId",                  
              "Author",
              "LastModifiedTime"
            ]
} ]
}

This will change the resource of above’s general sample response the following way:

"resource": {
   "@odata.type": "#microsoft.graph.listItem",
   "webUrl": "https://mmsharepoint.sharepoint.com/teams/MMTeamNo212/Freigegbene Dokumente/Dokument1.docx",
   "fields": {
     "title": "Dokument1",
     "listItemId": "3",
     "listID": "57f640c4-e7d7-...",
     "filename": "Dokument1.docx",
     "siteID": "5b3bbe35-75fc-...",
     "webId": "c60a39d3-b836-...",
     "author": "Markus Moeller;Markus Möller;Hans Hansen",
     "lastModifiedTime": "2019-06-19T15:04:00Z"
   }
 }

Of course only managed properties declared as retrievable can be used for that. And pay attention that only entityType=”listItem” returns fields but not the “driveItem”.

Sorting

To sort your results there is the possibility to handover fields together with sorting direction options (descending / ascending) inside the searchRequest:

{ "requests": [ 
{ "entityTypes": [ "driveItem" ], 
  "query": { "queryString": "*" }, 
  "sortProperties": [ { "name": "createdDateTime", "isDescending": "true" } ] 
} ]
}

This example searches for any driveItem and requests a result order of the most recent created items first as it chooses “createdDateTime” with descending sort order. Interestingly at the time of writing this post “sortProperties” is only documented on the “beta” endpoint of search but I tried it with v1.0 in Graph Explorer and there it’s working.

Paging

In the general sample’s result above there was a “moreResultsAvailable” flag set to true. This indicates there are more than the returned hits available. But also from the “total” attribute you could get how much items in total match the search criteria. By default only 25 hits are returned but this can be controlled with “size” and “from” to achieve a paging mechanism.

 { "requests": [
    {
     "entityTypes": [ "listItem" ],
     "query": { "queryString": "*" },
     "size": 100,
     "from": 100
    }  
]} 

This slightly enhanced example returns (max, if available) 100 items but begins “from” item 100 on so it skips the first 100 items you would have retrieved if you omitted the “from” parameter. “size” is not unlimited, even if it’s set to 9999 for instance there is a (Search)limit of 500 items returned per call.

To see the search endpoint of Microsoft Graph in action refer to the code repository of one of my last blogpost examples. There I implemented the configurable selection of retrieving documents either from a specific site / list or via Search.

This post is intended to give an overview about options and syntax how to search SharePoint items (and files as a side-effect) with Microsoft Graph. Once again I encourage everyone to give feedback and to keep this post up-to-date over the time where for sure new capabilities will arise. Thank you in advance for this.

Markus is a SharePoint architect and technical consultant with focus on latest technology stack in Microsoft 365 and SharePoint Online development. He loves the new SharePoint Framework as well as some backend stuff around Azure Automation or Azure Functions and also has a passion for Microsoft Graph.
He works for Avanade as an expert for Microsoft 365 Dev and is based in Munich.
Although if partially inspired by his daily work opinions are always personal.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s