×
Back to book

Custom Search Queries with C#Bot

This article will walkthrough how to add custom queries via your serverside project.

C#Bot supports custom search queries that allow end users to retrieve search results that are more relevant to their requirements. This article will walk through how to customize search queries and apply it to a collection on a customized page. For this project, we will be using the Codebots Zoo Project. You can follow along with the project by downloading the latest version from the public git page.

Create Custom Search in a new Rest Endpoint

Each animal has a keeper. Let's add a custom query to search the animals by the keeper's username by adding a new endpoint in serverside\src\Controllers\Entities\AnimalController.cs.

  1. Locate the protected region: // % protected region % [Add any further endpoints here] off begin
  2. Turn on the protected region by replacing off begin with on begin.
  3. Add a new endpoint as below
/// <summary>
/// Get the list of animuals by searching keeper's username
/// </summary>
/// <param name="qstr">The query string to search by</param>
/// <param name="dbContext">The database context</param>
/// <returns>The Event object with the given id</returns>
[HttpGet]
[Route("search-by-zookeeper-username")]
[Authorize]
public async Task<IEnumerable<Animal>> SearchByZooKeeperUsername(
    [FromQuery] string qstr,
    [FromServices] ZooDBContext dbContext)
{
    if (string.IsNullOrWhiteSpace(qstr))
    {
        return await dbContext.Animal.Include(a => a.ZooKeeper).ToListAsync();
    }

    qstr = qstr.ToLower();

    var result = await dbContext.Animal
        .Include(a => a.ZooKeeper)
        .Where(a => a.ZooKeeper.UserName.Contains(qstr))
        .ToListAsync();

    return result;
}

To use this endpoint in the front-end, open the clientside\src\Views\Pages\AnimalPage.tsx file. Locate the protected region // % protected region % [Add class properties here] off begin, replace the off with on, and finally add the following observable properties:

@observable
private search = { usernameToSearch: "" };
@observable
animalsSearchedByKeeperUsername: Animal[] = [];

Similarly, locate the protected region // % protected region % [Add class methods here] off begin, and replace off with on, and then add the following functions:

private customeSearchCollection = () => {
    const tableHeaders: ICollectionHeaderProps<Animal>[] = [
        {
            name: 'name',
            displayName: 'Name',
            sortable: true
        },
        {
            name: 'keeperUsername',
            displayName: 'Keeper Username',
            transformItem: animal => animal.zooKeeper.email
        }
    ]

    const searchCollection = (
        <>
            <h4>Example for custom search</h4>
            <h5>This search will only search the animals by it's zoo keeper's username</h5>
            <Collection
                selectableItems={true}
                headers={tableHeaders}
                onSearchTriggered={this.onSearchTriggered}
                collection={this.animalsSearchedByKeeperUsername}
                idColumn="id"
            />
        </>
    )

    return searchCollection;
}

private onSearchTriggered = (searchTerm: string) => {
    axios.get('/api/entity/animalentity/search-by-zookeeper-username', {params: {qstr: searchTerm}})
        .then(({data}) => {
            runInAction(
                () => {
                    this.animalsSearchedByKeeperUsername = data;
                }
            );
        });
}

Then add one line to render another search box and collection after the <AnimalTile> tag:

let contents = (
    <>
        <AnimalTile {...this.props} />
        {this.customeSearchCollection()}
    </>
);

When the front-end Animal page is rendered, it will display the search box and the collection we created below the search box. You can try it out by typing part of the zoo keeper's username (which is an email) and clicking the Go button. The collection should now display all the animals belonging and matching the zoo keepers.

Custom search logic through GraphQL

For now C#Bot doesn't support customizing special logic like searching by reference entity fields through GraphQL. This will be supported in future iterations.

Related articles