MongoDB 中的模糊搜尋

Mehvish Ashiq 2024年2月16日
  1. 什麼是模糊搜尋
  2. 在 MongoDB 中建立示例集合
  3. 使用 $regex 運算子在 MongoDB 中執行模糊搜尋
  4. 使用 $text 查詢在 MongoDB 中執行模糊搜尋
  5. 使用 JavaScript 的 Fuse.js 庫在 MongoDB 中執行模糊搜尋
MongoDB 中的模糊搜尋

今天,我們將討論模糊搜尋以及如何使用 MongoDB 進行模糊搜尋。

我們將從使用 $regex 運算子和 $text 查詢開始。此外,我們將學習使用名為 Fuse.js 的 JavaScript 庫對文件進行模糊搜尋。

什麼是模糊搜尋

使用模糊搜尋,我們可以搜尋不完全匹配但緊密匹配的文字。即使搜尋詞拼寫錯誤,查詢相關結果也很有用。

例如,即使輸入錯誤,谷歌也會向我們顯示與我們的搜尋詞相關的各種網頁。使用正規表示式(也稱為正規表示式)也是實現模糊搜尋的一種非常有益且省時的方法。

在 MongoDB 中建立示例集合

我們將從基礎到高階來學習模糊搜尋。為了練習它,讓我們建立一個名為 collection_one 的示例集合,它為每個文件都有一個欄位,即 name

_id 是自動建立的;我們不必創造它。你可以使用以下查詢來執行相同的操作。

示例程式碼:

> db.createCollection('collection_one')
> db.collection_one.insertMany([
    { name : 'Mehvish Ashiq'},
    { name : 'Jennifer Johnson'},
    { name : 'Natalie Robinson'},
    { name : 'John Ferguson'},
    { name : 'Samuel Patterson'},
    { name : 'Salvatore Callahan'},
    { name : 'Mikaela Christensen'}
])
> db.collection_one.find()

輸出:

{ "_id" : ObjectId("62939a37b3a0d806d251ddae"), "name" : "Mehvish Ashiq" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddaf"), "name" : "Jennifer Johnson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb0"), "name" : "Natalie Robinson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb1"), "name" : "John Ferguson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb3"), "name" : "Salvatore Callahan" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb4"), "name" : "Mikaela Christensen" }

使用 $regex 運算子在 MongoDB 中執行模糊搜尋

示例程式碼:

> db.collection_one.find({"name": /m/})

輸出:

{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }

在這段程式碼中,我們對 name 欄位執行模糊搜尋,並檢索 name 欄位包含字母 m 的所有文件。

如你所見,我們只有一個包含 m 字母的記錄,但還有兩個以 M(大寫字母)開頭的文件。為了處理這個問題,我們可以使用如下的 i 修飾符,它執行不區分大小寫的搜尋。

示例程式碼:

> db.collection_one.find({"name": /m/i})

輸出:

{ "_id" : ObjectId("62939a37b3a0d806d251ddae"), "name" : "Mehvish Ashiq" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb4"), "name" : "Mikaela Christensen" }

它表明正確設計的正規表示式非常重要;否則,我們可能會得到誤導性的結果。我們也可以通過以下方式來做同樣的事情。

示例程式碼(不區分大小寫的搜尋):

> db.collection_one.find({'name': {'$regex': 'm','$options': 'i'}})

輸出:

{ "_id" : ObjectId("62939a37b3a0d806d251ddae"), "name" : "Mehvish Ashiq" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb4"), "name" : "Mikaela Christensen" }

類似地,我們可以得到所有 name 以兩個字母組合結尾的文件作為 on

示例程式碼:

> db.collection_one.find({name:{'$regex' : 'on$', '$options' : 'i'}})

輸出:

{ "_id" : ObjectId("62939a37b3a0d806d251ddaf"), "name" : "Jennifer Johnson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb0"), "name" : "Natalie Robinson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb1"), "name" : "John Ferguson" }
{ "_id" : ObjectId("62939a37b3a0d806d251ddb2"), "name" : "Samuel Patterson" }

使用 $text 查詢在 MongoDB 中執行模糊搜尋

$text 查詢不適用於我們名為 collection_one 的示例集合,因為它沒有文字索引。因此,我們按如下方式建立索引。

示例程式碼:

> db.collection_one.createIndex({name:"text"});

如果指定的集合不存在,上面的語句也會建立它。請記住,我們可以在一個或多個用逗號分隔的欄位上建立索引。

請參閱以下示例。

db.collection_name.createIndex({name:"text", description:"text"});

建立索引後,我們可以進行模糊搜尋,如下所示。

示例程式碼:

> db.collection_one.find({ $text: { $search: "Mehvish" } } )

輸出:

{ "_id" : ObjectId("62939a37b3a0d806d251ddae"), "name" : "Mehvish Ashiq" }

使用 JavaScript 的 Fuse.js 庫在 MongoDB 中執行模糊搜尋

示例程式碼(fuzzysearch.js 檔案程式碼):

const Fuse = require('fuse.js')
var MongoClient = require('mongodb').MongoClient;
var url = 'mongodb://localhost:27017/';

MongoClient.connect(url, function(err, db) {
  if (err) throw err;
  var dbo = db.db('FuseFuzzySearch');

  var personObj = [
    {name: 'Mehvish Ashiq'}, {name: 'Jennifer Johnson'},
    {name: 'Natalie Robinson'}, {name: 'John Ferguson'},
    {name: 'Samuel Patterson'}, {name: 'Salvatore Callahan'},
    {name: 'Mikaela Christensen'}
  ];

  dbo.collection('person').insertMany(personObj, function(err, res) {
    if (err) throw err;
  });

  const options = {includeScore: true, keys: ['name']}

  const fuse = new Fuse(personObj, options);
  const result = fuse.search('jahson');
  console.log(result);
  db.close();
});

輸出:

[
  {
    item: { name: 'Jennifer Johnson', _id: 6293aa0340aa3b21483d9885 },
    refIndex: 1,
    score: 0.5445835311565898
  },
  {
    item: { name: 'John Ferguson', _id: 6293aa0340aa3b21483d9887 },
    refIndex: 3,
    score: 0.612592665952338
  },
  {
    item: { name: 'Natalie Robinson', _id: 6293aa0340aa3b21483d9886 },
    refIndex: 2,
    score: 0.6968718698752637
  },
  {
    item: { name: 'Samuel Patterson', _id: 6293aa0340aa3b21483d9888 },
    refIndex: 4,
    score: 0.6968718698752637
  }
]

在這個程式碼示例中,我們首先匯入了 fuse.js 庫。接下來,我們連線到 MongoDB。

如果由於任何原因未連線,則丟擲錯誤。否則,建立一個名為 FuseFussySearch 的資料庫。

然後,建立一個名為 personObj 的物件,其中包含我們要插入到 person 集合中的所有文件。如果在插入資料時出現任何問題,將會產生錯誤。

建立 Fuse 的物件,傳遞具有 keysincludeScore 的物件陣列 personObjoptions 以執行模糊搜尋並獲得結果,如上所示。

在這裡,keys 指定將執行搜尋的欄位。includeScore 是可選的,但最好有它,因為它告訴匹配分數。

如果它是 0,程式找到完美匹配,而 1 的分數表示完全不匹配。你可以在此處找到所有選項。

最後,不要忘記關閉連線。你還可以探索許多其他

作者: Mehvish Ashiq
Mehvish Ashiq avatar Mehvish Ashiq avatar

Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.

LinkedIn GitHub Facebook