0
0
Lập trình
Admin Team
Admin Teamtechmely

Tìm Kiếm Lai: Kết Hợp Tìm Kiếm Từ Khóa và Vector

Đăng vào 7 tháng trước

• 5 phút đọc

Giới thiệu

Trong loạt bài viết này, chúng ta đã tìm hiểu cách tối ưu hóa khả năng tìm kiếm cho ứng dụng tìm phim của mình bằng cách sử dụng tìm kiếm ngữ nghĩa (semantic search) và tìm kiếm vector (vector search). Ở phần cuối cùng này, chúng ta sẽ khám phá cách kết hợp cả hai phương pháp để tạo ra một công cụ tìm kiếm mạnh mẽ hơn với MongoDB Atlas thông qua toán tử $rankFusion.

Tại sao cần tìm kiếm lai?

Tìm kiếm phim không chỉ đơn thuần là tìm kiếm theo từ khóa. Người dùng thường tìm kiếm dựa trên những mảnh ghép ý tưởng, ví dụ như "một chiếc tàu chìm vào ban đêm sau khi va chạm với một tảng băng". Tuy nhiên, đôi khi họ cũng tìm kiếm theo tên cụ thể như "Titanic". Điều này cho thấy một vấn đề lớn: Không có một phương pháp tìm kiếm nào hoạt động hoàn hảo cho mọi loại truy vấn.

So sánh giữa tìm kiếm văn bản đầy đủ và tìm kiếm vector

  1. Tìm kiếm văn bản đầy đủ: Tìm các từ khóa chính xác hoặc biến thể của chúng trong các trường cụ thể như tiêu đề hoặc mô tả.
  2. Tìm kiếm vector: So sánh ý nghĩa tổng thể của truy vấn với ý nghĩa của tài liệu bằng cách sử dụng các embedding ngữ nghĩa.

Ví dụ thực tế

  • Trường hợp 1: Khi người dùng nhập "một chiếc tàu chìm vào ban đêm sau khi va chạm với một tảng băng":

    • Tìm kiếm vector sẽ tìm ra Titanic.
    • Tìm kiếm văn bản đầy đủ có thể trả về kết quả không liên quan.
  • Trường hợp 2: Khi ai đó tìm kiếm "Titanic":

    • Tìm kiếm vector có thể trả về Poseidon (một bộ phim khác về tàu chìm).
    • Tìm kiếm văn bản đầy đủ sẽ tìm thấy ngay lập tức.

Rõ ràng, cả hai phương pháp đều có ưu điểm riêng. Tìm kiếm văn bản đầy đủ tốt nhất cho các truy vấn chính xác, trong khi tìm kiếm vector xuất sắc khi truy vấn mô tả hoặc mơ hồ.

Tìm kiếm lai: Kết hợp ưu điểm của cả hai phương pháp

Với tìm kiếm lai, chúng ta kết hợp độ chính xác của tìm kiếm văn bản đầy đủ với trí thông minh của tìm kiếm ngữ nghĩa. MongoDB Atlas cho phép điều này thông qua toán tử $rankFusion, cho phép chúng ta kết hợp và tái xếp hạng kết quả từ nhiều pipeline khác nhau.

Điều kiện tiên quyết

Trước khi bắt đầu, hãy đảm bảo rằng bạn đã thiết lập một cụm MongoDB Atlas, Java 17+, một token API của Voyage AI và bộ sưu tập embedded_movies. Version MongoDB Atlas cần từ 8.1 trở lên để sử dụng toán tử $rankFusion.

Tìm kiếm vector

Ứng dụng của chúng ta hiện đang sử dụng tìm kiếm vector với các bộ lọc trước. Điều này có nghĩa là chúng ta có thể thực hiện các truy vấn ngữ nghĩa trong khi thu hẹp không gian tìm kiếm theo năm, thể loại và đánh giá IMDb.

json Copy
[
 {
 $vectorSearch: {
 filter: {
 $and: [
 { genres: { $in: ["Action", "Drama"] } },
 { year: { $gte: 1980, $lte: 2003 } },
 { "imdb.rating": { $gte: 9.0 } }
 ]
 },
 index: "vector_index",
 limit: 8,
 numCandidates: 160,
 path: "plot_embedding_voyage_3_large",
 queryVector: [
 -0.027284348, ....
 ]
 }
 }
]

Tìm kiếm văn bản đầy đủ

Mặc dù tìm kiếm vector rất hữu ích cho các truy vấn mô tả, nhưng nó không phải lúc nào cũng là lựa chọn tốt nhất. Khi người dùng biết chính xác tiêu đề, tìm kiếm văn bản đầy đủ có thể nhanh chóng tìm thấy tài liệu đó mà không cần phải tạo embedding.

Thực hiện chỉ mục văn bản đầy đủ

Chạy lệnh sau trong shell MongoDB của bạn để tạo một chỉ mục tìm kiếm động trên bộ sưu tập embedded_movies:

json Copy
db.embedded_movies.createSearchIndex(
 "fulltextsearch",
 { mappings: { dynamic: true } }
)

Thực hiện truy vấn văn bản cơ bản

Với chỉ mục đã được tạo, chúng ta có thể thực hiện một truy vấn đơn giản để tìm kiếm "Titanic" theo tiêu đề:

json Copy
db.embedded_movies.aggregate([
 {
 $search: {
 index: "fulltextsearch",
 text: {
 query: "Titanic",
 path: "title"
 }
 }
 },
])

Cải thiện trải nghiệm với tìm kiếm mơ hồ

Một vấn đề phổ biến là lỗi chính tả. Nếu người dùng nhập "titani" thay vì "Titanic", tìm kiếm chính xác sẽ không trả về kết quả. Chúng ta có thể sử dụng tùy chọn mơ hồ để cải thiện điều này.

json Copy
db.embedded_movies.aggregate([
 {
 $search: {
 index: "fulltextsearch",
 text: {
 query: "titani",
 path: "title",
 fuzzy: {
 maxEdits: 1
 }
 }
 }
 }
])

Tăng cường kết quả bằng cách tăng điểm

Để đảm bảo các trường quan trọng hơn được ưu tiên trong kết quả tìm kiếm, chúng ta có thể áp dụng tăng cường điểm cho các trường khác nhau.

json Copy
db.embedded_movies.aggregate([
 {
 $search: {
 index: "fulltextsearch",
 compound: {
 should: [
 {
 text: {
 query: "titanic",
 path: "title",
 fuzzy: {
 maxEdits: 1
 },
 score: {
 boost: { value: 4.0 }
 }
 }
 },
 {
 text: {
 query: "titanic",
 path: "plot",
 fuzzy: {
 maxEdits: 1
 },
 score: {
 boost: { value: 3.0 }
 }
 }
 },
 {
 text: {
 query: "titanic",
 path: "fullplot",
 fuzzy: {
 maxEdits: 1
 },
 score: {
 boost: { value: 2.0 }
 }
 }
 }
 ]
 }
 }
 }
]
)

Kết hợp sức mạnh của tìm kiếm lai

Chúng ta đã có cả hai thành phần:

  • Tìm kiếm vector cho sự hiểu biết ngữ nghĩa
  • Tìm kiếm văn bản đầy đủ cho độ chính xác với tùy chọn mơ hồ và tăng điểm

Toán tử $rankFusion

Toán tử $rankFusion cho phép chúng ta chạy nhiều pipeline tìm kiếm trong cùng một tập hợp, sau đó kết hợp kết quả của chúng thành một đầu ra xếp hạng duy nhất. Cấu trúc cơ bản của một truy vấn lai sử dụng $rankFusion sẽ như sau:

json Copy
[
 {
 $rankFusion: {
 input: {
 pipelines: {
 searchPipeline: [],
 vectorPipeline: []
 }
 },
 combination: {
 weights: {
 searchPipeline: 0.5,
 vectorPipeline: 0.5
 }
 },
 scoreDetails: false
 }
 }
]

Cách quyết định trọng số phù hợp

Trọng số cho từng pipeline phụ thuộc vào cách người dùng tương tác với ứng dụng. Hãy thử nghiệm với dữ liệu của bạn để tìm ra sự cân bằng tốt nhất cho trải nghiệm người dùng.

Kết luận

Chúng ta đã khám phá cách vượt ra ngoài các phương pháp tìm kiếm truyền thống và xây dựng các ứng dụng thông minh với MongoDB. Đừng quên tham gia cộng đồng MongoDB để đặt câu hỏi và chia sẻ kinh nghiệm của bạn. Nếu bạn muốn xem mã nguồn đầy đủ từ loạt bài này, hãy tìm thấy nó trên GitHub.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào