Flutter数据库全文搜索插件sqlite_bm25的使用

Flutter数据库全文搜索插件sqlite_bm25的使用

sqlite_bm25 是一个为 SQLite FTS4(全文搜索)扩展实现 Okapi BM25 算法的插件。它可以帮助开发者在 Flutter 应用中进行更精确的全文搜索。

示例代码

以下是一个完整的示例,展示了如何在 Flutter 中使用 sqlite_bm25 插件进行全文搜索。

import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:sqlite_bm25/sqlite_bm25.dart';

void main() async {
  // 初始化数据库
  WidgetsFlutterBinding.ensureInitialized();
  final databasePath = await getDatabasesPath();
  final path = "$databasePath/example.db";
  final db = await openDatabase(path, version: 1, onCreate: (db, version) async {
    await db.execute('CREATE VIRTUAL TABLE $table USING fts4(name)');
  });

  // 插入数据
  await db.insert(table, {'rowid': 1, 'name': 'Sam Rivers'});
  await db.insert(table, {'rowid': 2, 'name': 'Samwise "Sam" Gamgee'});
  await db.insert(table, {'rowid': 3, 'name': 'Sam'});
  await db.insert(table, {'rowid': 4, 'name': 'Sam Seaborn'});
  await db.insert(table, {'rowid': 5, 'name': 'Samwell "Sam" Tarly'});

  // 执行查询
  var rows = await db.query(
    table,
    columns: [
      'name',
      'matchinfo($table, \'pcx\') as info', // 使用 BM25 格式字符串
    ],
    where: '$table MATCH ?',
    whereArgs: ['sam'],
  );

  rows = rows.map((row) {
    return {
      'name': row['name'],
      'rank': bm25(row['info']), // 计算 BM25 排名
    };
  }).toList();

  // 对结果进行排序
  rows.sort((a, b) => a['rank'].compareTo(b['rank']));

  // 获取排名前三的结果
  final names = rows.take(3).map((r) => r['name']).join(', ');

  print(names);

  // 关闭数据库连接
  await db.close();
}

// 示例表名
final String table = 'bm25_test';

代码解释

  1. 初始化数据库

    final databasePath = await getDatabasesPath();
    final path = "$databasePath/example.db";
    final db = await openDatabase(path, version: 1, onCreate: (db, version) async {
      await db.execute('CREATE VIRTUAL TABLE $table USING fts4(name)');
    });
    

    这段代码初始化了一个内存数据库,并创建了一个虚拟表 bm25_test,该表使用 FTS4 全文搜索引擎。

  2. 插入数据

    await db.insert(table, {'rowid': 1, 'name': 'Sam Rivers'});
    await db.insert(table, {'rowid': 2, 'name': 'Samwise "Sam" Gamgee'});
    await db.insert(table, {'rowid': 3, 'name': 'Sam'});
    await db.insert(table, {'rowid': 4, 'name': 'Sam Seaborn'});
    await db.insert(table, {'rowid': 5, 'name': 'Samwell "Sam" Tarly'});
    

    这些代码向 bm25_test 表中插入了五条记录。

  3. 执行查询

    var rows = await db.query(
      table,
      columns: [
        'name',
        'matchinfo($table, \'pcx\') as info', // 使用 BM25 格式字符串
      ],
      where: '$table MATCH ?',
      whereArgs: ['sam'],
    );
    

    这段代码使用 MATCH 来搜索包含关键词 sam 的记录,并返回匹配信息。

  4. 计算 BM25 排名并排序

    rows = rows.map((row) {
      return {
        'name': row['name'],
        'rank': bm25(row['info']), // 计算 BM25 排名
      };
    }).toList();
    
    rows.sort((a, b) => a['rank'].compareTo(b['rank']));
    

    这段代码计算每条记录的 BM25 分数,并按分数对结果进行排序。

  5. 获取排名前三的结果

    final names = rows.take(3).map((r) => r['name']).join(', ');
    print(names);
    

    这段代码获取排名前三的结果,并将它们以逗号分隔的形式打印出来。

  6. 关闭数据库连接

    await db.close();
    

更多关于Flutter数据库全文搜索插件sqlite_bm25的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter数据库全文搜索插件sqlite_bm25的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


sqlite_bm25 是一个用于在 Flutter 中实现 SQLite 数据库全文搜索的插件。它基于 SQLite 的 FTS5 扩展,提供了高效的全文搜索功能。以下是如何在 Flutter 项目中使用 sqlite_bm25 插件的步骤:

1. 添加依赖

首先,在 pubspec.yaml 文件中添加 sqlite_bm25 插件的依赖:

dependencies:
  flutter:
    sdk: flutter
  sqlite_bm25: ^0.1.0  # 请检查最新版本

然后运行 flutter pub get 以安装依赖。

2. 初始化数据库

在使用 sqlite_bm25 之前,你需要初始化 SQLite 数据库,并创建支持全文搜索的表。

import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'package:sqlite_bm25/sqlite_bm25.dart';

Future<Database> initializeDatabase() async {
  // 获取数据库路径
  String path = join(await getDatabasesPath(), 'app_database.db');

  // 打开数据库
  Database database = await openDatabase(
    path,
    onCreate: (db, version) async {
      // 创建支持全文搜索的表
      await db.execute('''
        CREATE VIRTUAL TABLE documents USING fts5(
          id, title, content,
          tokenize = 'porter'
        );
      ''');
    },
    version: 1,
  );

  return database;
}

3. 插入数据

你可以向表中插入一些数据,以便后续进行全文搜索。

Future<void> insertData(Database database) async {
  await database.insert('documents', {
    'id': 1,
    'title': 'Flutter Development',
    'content': 'Flutter is a UI toolkit for building natively compiled applications.',
  });

  await database.insert('documents', {
    'id': 2,
    'title': 'Dart Programming',
    'content': 'Dart is a client-optimized language for fast apps on any platform.',
  });

  // 插入更多数据...
}

4. 执行全文搜索

使用 sqlite_bm25 插件执行全文搜索。

Future<List<Map<String, dynamic>>> searchDocuments(Database database, String query) async {
  // 使用 BM25 算法进行全文搜索
  List<Map<String, dynamic>> results = await database.rawQuery('''
    SELECT id, title, content, bm25(documents) AS score
    FROM documents
    WHERE documents MATCH ?
    ORDER BY score;
  ''', [query]);

  return results;
}

5. 使用示例

以下是一个完整的示例,展示如何初始化数据库、插入数据并执行全文搜索。

import 'package:flutter/material.dart';
import 'package:sqflite/sqflite.dart';
import 'package:path/path.dart';
import 'package:sqlite_bm25/sqlite_bm25.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  // 初始化数据库
  Database database = await initializeDatabase();

  // 插入数据
  await insertData(database);

  // 执行全文搜索
  String query = 'Flutter';
  List<Map<String, dynamic>> results = await searchDocuments(database, query);

  // 打印搜索结果
  print('Search results for "$query":');
  for (var result in results) {
    print('ID: ${result['id']}, Title: ${result['title']}, Score: ${result['score']}');
  }

  // 关闭数据库
  await database.close();
}

Future<Database> initializeDatabase() async {
  String path = join(await getDatabasesPath(), 'app_database.db');

  Database database = await openDatabase(
    path,
    onCreate: (db, version) async {
      await db.execute('''
        CREATE VIRTUAL TABLE documents USING fts5(
          id, title, content,
          tokenize = 'porter'
        );
      ''');
    },
    version: 1,
  );

  return database;
}

Future<void> insertData(Database database) async {
  await database.insert('documents', {
    'id': 1,
    'title': 'Flutter Development',
    'content': 'Flutter is a UI toolkit for building natively compiled applications.',
  });

  await database.insert('documents', {
    'id': 2,
    'title': 'Dart Programming',
    'content': 'Dart is a client-optimized language for fast apps on any platform.',
  });
}

Future<List<Map<String, dynamic>>> searchDocuments(Database database, String query) async {
  List<Map<String, dynamic>> results = await database.rawQuery('''
    SELECT id, title, content, bm25(documents) AS score
    FROM documents
    WHERE documents MATCH ?
    ORDER BY score;
  ''', [query]);

  return results;
}
回到顶部