MongoDB中的完整和部分文字搜尋

banq發表於2024-05-08

開發資料庫應用程式時經常需要快速高效的文字搜尋。他們還應該支援完整和部分文字匹配,以使這些搜尋更加使用者友好。為此,MongoDB 提供了幾種使用文字搜尋查詢相關文件的方法。

在本教程中,我們將探討 MongoDB 中的文字搜尋、其功能、如何使用它以及如何充分利用它。

MongoDB 中的文字搜尋
雖然文字搜尋查詢是一個強大的工具,但它們需要特定的設定。為了實現這一點,我們需要在集合上建立一個文字索引。

索引就像特殊的資料夾,只儲存集合中每個文件的一點資訊。換句話說,它們與實際文件本身是分開的。此外,MongoDB 允許使用者建立不同型別的索引。

幸運的是,MongoDB 提供了文字索引,旨在促進字串內容中的搜尋。這些索引非常靈活,可以涵蓋多個領域,可以進行全面的搜尋。此外,這些索引有助於資料庫更快地搜尋集合。

首先,我們透過指定連線字串、資料庫名稱和集合名稱來建立資料庫客戶端:

@Before
public static void setup() {
    if (mongoClient == null) {
        mongoClient = MongoClients.create(<font>"mongodb://localhost:27017");
        database = mongoClient.getDatabase(
"baeldung");
        collection = database.getCollection(
"user");
    }
}

我們還在集合的欄位上建立一個文字索引:

void createTextIndex(String field) {
    IndexOptions indexOptions = new IndexOptions();
    indexOptions.name(<font>"textIndex").unique(false).background(true);
    collection.createIndex(Indexes.text(field), indexOptions);
}

有一個限制:一個集合只能有一個專用的文字搜尋索引。

全文檢索
簡單的全文搜尋非常簡單。我們可以輸入關鍵字或短語,然後系統會找到包含這些確切術語的文件。

除了簡單的全文搜尋之外,還有多種方法可以執行全文搜尋。每個都有自己的優點,並且是針對特定用例量身定製的。其中一些常見的方式包括布林全文搜尋、短語搜尋和鄰近搜尋。

讓我們建立一個執行文字搜尋查詢的方法:

List<Document> searchUser(String query) {
    Document result = new Document(<font>"$text", new Document("$search", name));
    return collection.find(result).into(new ArrayList<>());
}

$text對使用文字索引索引的欄位的內容執行文字搜尋,而$search定義要搜尋的目標文字。此外,$text使用空格對搜尋字串進行標記,並對搜尋字串中的所有此類標記執行邏輯或。這意味著當搜尋“Java Spring”時,我們會找到所有帶有“Java”或“Spring”甚至兩者都帶有“Java”或“Spring”的文件。

讓我們建立一些記錄來探索全文搜尋功能:

@Test
void whenSearchingUserWithFullText_thenCorrectCountReturned() {
    <font>// WHEN<i>
    insertUser(
"Leonel", "Java Spring");
    insertUser(
"John", "Java Spring MongoDB");
    insertUser(
"Smith", "Java");
    createTextIndex(
"description");
   
// THEN<i>
    assertEquals(
"All users with term 'Java' or 'Spring'", 3, searchUser("Java Spring").size());
}

我們還可以透過在搜尋查詢中新增“-”字元來排除某個單詞:
assertEquals("All users with term 'Java' or 'Spring' but not 'MongoDB'", 2, searchUser("Java Spring -MongoDB").size());

同樣,我們也可以透過將它們括在雙引號中來搜尋精確的短語:
assertEquals("All users with term Java only", 1, searchUser("\"Java\"").size());

部分文字搜尋
MongoDB 本身不支援部分搜尋。與全文搜尋不同,部分搜尋、模糊搜尋或子字串搜尋並不簡單。搜尋功能應用特定於語言的停用詞和詞幹規則。

支援的語言的詞幹規則基於標準演算法,該演算法處理常見動詞和名詞,並且通常不知道專有名詞。 

讓我們嘗試使用部分搜尋來搜尋使用者:

@Test
void whenSearchingUserWithPartialText_thenCorrectCountReturned() {
    <font>// WHEN<i>
    insertUser(
"LEONEL", "Java Spring");
    createTextIndex(
"name");
   
// THEN<i>
    assertEquals(
"Search with capital case", 1, mongoDBClient.searchUser("LEONEL").size());
    assertEquals(
"Search with lower case", 1, mongoDBClient.searchUser("leonel").size());
    assertEquals(
"Partial search", 1, mongoDBClient.searchUser("LEONE").size());
}

相反,由於詞幹規則,系統無法定位“L”、“LEO”或“NEL”:

assertEquals(<font>"Partial search with L", 0, searchUser("L").size());
assertEquals(
"Partial search with LEO", 0, searchUser("LEO").size());
assertEquals(
"Partial search with NEL", 0, searchUser("NEL").size());


部分搜尋的解決方法之一是使用$regex。因此,我們不需要文字索引,如果集合很大,這可能會減慢搜尋操作。 
 

相關文章