Repository: nomic-ai/gpt4all
File: gpt4all-chat/src/database.cpp (C++)

Code before:
{
    struct SearchResult { int chunkId; float score; };
    QList<BM25Query> bm25Queries = queriesForFTS5(query);

    QSqlQuery sqlQuery(m_db);
    sqlQuery.prepare(SELECT_CHUNKS_FTS_SQL.arg(collections.join("', '"), QString::number(k)));

    bool foundQuery = false;
    QList<SearchResult> results;
    for (auto &bm25Query : std::as_const(bm25Queries)) {
        sqlQuery.addBindValue(bm25Query.query);

        if (!sqlQuery.exec()) {
            qWarning() << "Database ERROR: Failed to execute BM25 query:" << sqlQuery.lastError();
            return {};
        }

        if (sqlQuery.next()) {
            // Save the query that was used to produce results
            foundQuery = true;
            bm25q = bm25Query;
            break;
        }
    }

    if (foundQuery) {
        do {
            const int chunkId = sqlQuery.value(0).toInt();
            const float score = sqlQuery.value(1).toFloat();
            results.append({chunkId, score});
        } while (sqlQuery.next());
    }

    k = qMin(k, results.size());
    std::partial_sort(
        results.begin(), results.begin() + k, results.end(),
        [](const SearchResult &a, const SearchResult &b) { return a.score < b.score; }
    );

    QList<int> chunkIds;
    chunkIds.reserve(k);
    for (int i = 0; i < k; i++)
        chunkIds << results[i].chunkId;
    return chunkIds;
}

float Database::computeBM25Weight(const Database::BM25Query &bm25q)
{
    float bmWeight = 0.0f;
    if (bm25q.isExact) {
        bmWeight = 0.9f; // the highest we give

Review comment (suggestion):
Technically this boolean is redundant. We could consider directly checking whether the query is positioned on a valid record:
```suggestion
    if (sqlQuery.at() != QSql::AfterLastRow) {
```

Code after:
    b.qlength = 1; // length of phrase
    b.ilength = oWords.size();
    b.rlength = oWords.size() - quotedWords.size();
    queries << b;
    return queries;
}

QList<int> Database::searchBM25(const QString &query, const QList<QString> &collections, BM25Query &bm25q, int k)
{
    struct SearchResult { int chunkId; float score; };
    QList<BM25Query> bm25Queries = queriesForFTS5(query);

    QSqlQuery sqlQuery(m_db);
    sqlQuery.prepare(SELECT_CHUNKS_FTS_SQL.arg(collections.join("', '"), QString::number(k)));

    QList<SearchResult> results;
    for (auto &bm25Query : std::as_const(bm25Queries)) {
        sqlQuery.addBindValue(bm25Query.query);

        if (!sqlQuery.exec()) {
            qWarning() << "Database ERROR: Failed to execute BM25 query:" << sqlQuery.lastError();
            return {};
        }

        if (sqlQuery.next()) {
            // Save the query that was used to produce results
            bm25q = bm25Query;
            break;
        }
    }

    if (sqlQuery.at() != QSql::AfterLastRow) {
        do {
            const int chunkId = sqlQuery.value(0).toInt();
            const float score = sqlQuery.value(1).toFloat();
            results.append({chunkId, score});
        } while (sqlQuery.next());
    }

    k = qMin(k, results.size());
    std::partial_sort(
        results.begin(), results.begin() + k, results.end(),
        [](const SearchResult &a, const SearchResult &b) { return a.score < b.score; }
    );

    QList<int> chunkIds;
    chunkIds.reserve(k);
    for (int i = 0; i < k; i++)
        chunkIds << results[i].chunkId;
    return chunkIds;
}