Creating a Glossary

Even tho the last reply is a bit older, I felt like sharing my solution in case anyone stumbles across this thread.
I created a DataviewJs Script inspired by Meastn’s Design. The difference between the Dataview DQL Queries provided by @Edmund and @statmonkey is that my Query includes some parts of the note. This obviously comes with some performance downsides since the note contents have to be fetched. However now I don’t have to write my Definition as metadata but just have it in the note content.

The resulting glossary looks like this: (Theme: Encore, with some custom CSS snippets)

A note for a glossary entry could look like this:

My Frontmatter looks like this:

---
tags:
  - "#glossar"
related: "[[Test Entry]]"
topic: German
---

The DataviewJs Script I am using might be a bit bloated and could be written simpler, but this is what I am working with. I tried to add enough comments so that it’s clear even for inexperienced JS users.

// Define custom values
const tagName = "#glossar";
const mySectionName = "Definition";

/**
 * Returns a substring of the given markDownstring which will be the content of the
 * given section. Leading and trailing spaces will be trimmed.
 * The markdownstring should include the given sectionName with 1 to 5 (both inclusive)
 * hashtags in front with optional spaces in between. The section with the given
 * sectionName may be the last section in the markDownString.
 * @param markDownString a markdown formatteed string which contains the section to be searched for
 * @param sectionName    the name of the section to be searched for in the markDownString
 * @returns a substring of the markdownstring which is exactly the searched for section content (spaces trimmes)
 * or if the given section is not found: "<span>-</span>"
 */
const getSectionContent = (markDownString, sectionName) => {
    // match between 1 to 5 hashtags and optional spaces before the sectionName
    const sectionPattern = new RegExp("#{1,5}\\s*" + sectionName);
    // match between 1 to 5 hashtags
    const nextSectionPattern = new RegExp("#{1,5}");

    // check if sectionName can be found in the markDownString
    let sectionHeaderLength;
    if (sectionPattern.test(markDownString)) {
        sectionHeaderLength = markDownString.match(sectionPattern)[0].length;
    } else {
        return "<span>-</span> "; // break with custom string since section not found
    }

    const startingIndex = markDownString.search(sectionPattern);
    // search for a next section starting after the found sectionName
    const endingIndex = markDownString.substring(startingIndex + sectionHeaderLength)
        .search(nextSectionPattern);

    // Check if a next section exists or end of string has been reached
    if (endingIndex == -1) {
        return markDownString.substring(startingIndex + sectionHeaderLength).trim();
    } else {
        return markDownString.substring(
            startingIndex + sectionHeaderLength, // remove the section header
            startingIndex + sectionHeaderLength + endingIndex // add starting point since endingIndex is determined of substring
        );
    }
};

// == Render a table for each starting character ==
// group all notes with tag #glossar by the first character of the note file name
const groupedTableEntries = dv.pages(tagName).groupBy(note => note.file.name.charAt(0).toUpperCase());
for (let group of groupedTableEntries) {

    const tableEntries = await Promise.all(
        group.rows // all entries for the current group aka current table
            .map(async (note) => {
                const content = await dv.io.load(note.file.path); // load the note content
                // map pages to custom object which contains all needed data
                return {
                    name: note.file.name,
                    link: note.file.link,
                    definition: getSectionContent(content, mySectionName), // get the section content
                    topic: note.topic,
                    related: note.related
                };
            })
    );


    dv.header(3, group.key); // show the character as the header
    dv.table(["Begriff", "Definition","Thema", "Verwandt"],
        tableEntries
        .sort((entryA, entryB) => entryA.name.localeCompare(entryB.name))
        .map(entry => [entry.link, entry.definition, entry.topic, entry.related])
    )
}

The script is inspired by S-Blu Github Pages, the Dataviews Codeblock Examples and this Post in a Showcase Thread