Pnpjs: Adding a filter to the search query while using ISearchQuery interface

Created on 24 Aug 2020  路  7Comments  路  Source: pnp/pnpjs

Category

  • [ ] Enhancement
  • [ ] Bug
  • [X] Question
  • [ ] Documentation gap/issue

Version

Please specify what version of the library you are using: [ @pnp/[email protected] ]

Please specify what version(s) of SharePoint you are targeting: [ 16.0.0.20405 ]

If you are not using the latest release, please update and see if the issue is resolved before submitting an issue.

Expected / Desired Behavior / Question

Is there a way to filter a search query based on a property value while still using the ISeachQuery interface?
I need to page the results so filtering after the query is not an option.

code details needed question

All 7 comments

Can you provide a raw REST sample of what a request you're going to construct?

Usually, you page search results using RowLimit and StartRow:

const { PrimarySearchResults } = await sp.search({
  Querytext: '*',
  RowLimit: 10,
  StartRow: 0
});

console.log(PrimarySearchResults);

Can't imagine what can be achieved with $filter in that context.

I am using RowLimit and StartRow, but I have a property pane string value, "searchValue", that the query results need to be filtered by, but if I filter the PrimarySearchResults returned from the query with something like this:

if (PrimarySearchResults.length > 0) {
              let regEx = new RegExp("\\b" + searchValue + "\\b", "i");
              if (searchValue !== undefined && searchValue !== "") {
                filteredResults = PrimarySearchResults.filter((item) => {
                  let result = item.Title.match(regEx);
                  if (result) return item;
                });
              }

Then the paging module doesn't present the results in the manner I need, of course, the results are taken from the larger query that does know about RowLimt and StartRow and then filtered to a new array and dumped into the first page.

I hope I've made what I am trying to achieve understandable.

Here is part of my search query code.

private newsArchiveSearch(
    queryText: string,
    searchValue: string,
    rowLimit: number,
    highPrioritySort = false,
    currentPage: number,
    totalPages: number
  ): Promise<INews[]> {
    return new Promise<INews[]>(
      (
        resolve: (news: INews[]) => void,
        reject: (error: any) => void
      ): void => {
        rowLimit = totalPages;
        let startRow = (currentPage - 1) * 10 ;

        let query = <SearchQuery>{
          Querytext: queryText,
          StartRow: startRow,
          RowLimit: rowLimit,
          TrimDuplicates: false,

          SelectProperties: [
            "PictureThumbnailURL",
            "Title",
            "Path",
            "FirstPublishedDate",
            "Description",
            "SPWebUrl",
            "SiteName",
          ],

Adhoc post-filtering won't work with server-side pagination.

OData $filter can't be used with the search API as well.

The filtering condition must be a part of the Querytext which is not just the searched text but can be a sophisticated KQL statement. The other possible option is using refiners for filtering too.

Some scenarios, which doesn't suite KQL capabilities might require extending search scheme or forcing users searching for the data following Search limitations. Or making unoptimized requests with greater RowLimit and client-side filtering and pagination.

I think RefinementFilters should work in this case.

const { PrimarySearchResults } = await sp.search({
  Querytext: '*',
  RowLimit: 10,
  StartRow: 0,
  RefinementFilters : ["and(lastname:equals("burr"),firstname:equals("bill"))"],
});

console.log(PrimarySearchResults);

Thanks koltyakov! I just altered my KQL Querytext to include the value from the property pane. Works great!

Great!

tavikukko, Curious, how is the matching with the equals() method? If I need it to match whole words in the "title"? Does equals() work like that, or is there another method? Just for future reference...

Was this page helpful?
0 / 5 - 0 ratings