DEV Community

Cover image for A search engine - Part 3: Searching the index
David Kröll
David Kröll

Posted on

A search engine - Part 3: Searching the index

In the last episode we completed the algorithm for adding entries to our cache and index data structure.
This episode will cover the querying and retrieval of data.

The main part in our query algorithm is to check if the word we searched for does exist in our index map.
If that's the case, the assigned items from the cache are returned to the caller.

First, we'll define a custom type for our search results which will be returned from our method.

// SearchResult represents a result set returned from a search execution
type SearchResult struct {
    Filter   string
    Matches  int
    Contents []string
Enter fullscreen mode Exit fullscreen mode

The Find() func checks the index for occurences and if successful attaches the according entries from our cache.
It also returns a total match counter.

// Find queries the index and returns all results from the cache
func (g *GlSearch) Find(s string) SearchResult {

    // create response
    sr := SearchResult{
        Filter: s,

    contents := []string{}

    // split up using the same func as in part 1
    words := split(s, g.config.Seperators)

    for _, v := range words {

        // transform our search input again
        v = g.config.TransformFunc(v)

        // check map if there is a matching entry in our index
        if e, ok := g.index[v]; ok {

            // retrieve the occurences from our cache by traversing through the index
            for _, ci := range e {
                contents = append(contents, g.cache[ci])


    sr.Contents = contents

    return sr
Enter fullscreen mode Exit fullscreen mode

So at this point we're finished with the basic implementation of our inverted index.
The three methods we defined in part 1 are now fully functional.

In the next episode we'll discuss some synchronization and thread safety features.

Top comments (0)