2016-07-05 14 views
15

Tôi đang sử dụng MongoDB, và tôi có một bộ sưu tập các tài liệu với cấu trúc sau:Index Bounds trên Mongo Regex Tìm kiếm

{ 
    fName:"Foo", 
    lName:"Barius", 
    email:"[email protected]", 
    search:"foo barius" 
} 

Tôi đang xây dựng một chức năng mà sẽ thực hiện tìm kiếm biểu hiện thường xuyên trên các lĩnh vực search . Để tối ưu hóa hiệu suất, tôi đã lập chỉ mục bộ sưu tập này trên trường tìm kiếm. Tuy nhiên, mọi thứ vẫn còn hơi chậm. Vì vậy, tôi chạy một explain() trên một truy vấn mẫu:

db.Collection.find({search:/bar/}).explain(); 

Nhìn theo kế hoạch chiến thắng, tôi thấy các giới hạn chỉ số sau đây được sử dụng:

"search": [ 
     "[\"\", {})", 
     "[/.*bar.*/, /.*bar.*/]" 
] 

Tập thứ hai làm cho tinh thần - nó nhìn từ bất cứ thứ gì có chứa thanh vào bất kỳ thứ gì có chứa thanh. Tuy nhiên, tập đầu tiên làm tôi bối rối. Dường như nó nằm trong giới hạn của "", bao gồm {} độc quyền. Tôi lo ngại rằng tập hợp các giới hạn này đang làm chậm truy vấn của tôi. Nó có cần thiết để giữ không? Nếu không, làm thế nào tôi có thể ngăn không cho nó được đưa vào?

+0

Có cùng một vấn đề, bạn đã tìm thấy một lời giải thích? – kirhgoff

+0

@kirhgoff Bạn đang sử dụng phiên bản mongoDB nào? – barbakini

+0

@kirhgoff bạn đang sử dụng 'mongoDB native' hoặc' mongoose'. Kiểm tra điều này - http://voidcanvas.com/mongoose-vs-mongodb-native/ –

Trả lời

5

Tôi nghĩ đó chỉ là cách mongodb hoạt động với regex (xem https://scalegrid.io/blog/mongodb-regular-expressions-indexes-performance/). Chỉ cần xem ra cho giá trị nscanned/totalKeysExamined, nếu nó quá lớn thì chỉ mục là vô ích cho truy vấn của bạn.

Xem thêm: MongoDB, performance of query by regular expression on indexed fields

+0

Đồng ý, như đã nêu trong tài liệu MongoDB và trong https://stackoverflow.com/a/33219393/8291949 nếu regex của bạn không phải là một "tiền tố biểu hiện" mongo sẽ quét toàn bộ các phím trong chỉ mục sau đó sẽ lấy các tài liệu phù hợp (mà nên được vẫn còn nhanh hơn một bộ sưu tập đầy đủ quét). – wp78de

0

Đây là cách Mongo làm việc với loại regex và một chỉ mục. Ý tôi là bạn đang tìm kiếm/bar/thay vì/^ bar /.

Khi bạn chỉ định một chỉ mục trên trường đó, nó sẽ lập chỉ mục từ ký tự đầu tiên. Vì vậy, "Foo barius" được lập chỉ mục bắt đầu bằng F. Vì bạn đang tìm kiếm "bar" ở bất kỳ đâu trong trường, bạn phải tìm kiếm toàn bộ chỉ mục trên trường đó đang tìm * thanh *.

Dòng đầu tiên trong giải thích của bạn cho biết xem xét mọi bản ghi trong chỉ mục.

Dòng thứ hai cho biết, chỉ cho tôi những chỉ số đó từ (1) có thanh trong đó.

Tóm tắt: Thiết kế hồ sơ của bạn để họ sử dụng chỉ mục một cách hiệu quả. Trong trường hợp chuỗi, hãy đảm bảo tìm kiếm của bạn ở đầu chuỗi, ví dụ:/^ bar /. Nếu tôi sẽ tìm kiếm theo họ, sau đó nó cần phải xảy ra đầu tiên trong một trường được lập chỉ mục.

Làm bài tập giải thích trên/^ bar/thay thế. Bạn sẽ không nhận được dữ liệu của bạn, nhưng giới hạn chỉ mục đầu tiên sẽ giống như/^ bar/to/^ bas /.

Tôi hy vọng luồng câu trả lời ý thức của tôi hữu ích.

UDude

-1

Tôi nghĩ tôi nên thêm hai xu.

Hai câu trả lời trước là chính xác. Biểu thức regex chỉ có thể sử dụng chỉ mục chuẩn nếu bạn bắt đầu tìm kiếm của mình ngay từ đầu. Trên thực tế, có một chỉ mục và tìm kiếm bằng regex có thể có ảnh hưởng bất lợi đến tìm kiếm của bạn bởi vì nó cố gắng sử dụng chỉ mục nhưng sẽ không thành công.

Có một loại chỉ mục khác có thể hữu ích trong trường hợp của bạn. Chỉ mục văn bản của Mongo.Nó chỉ mỗi từ dựa trên không gian, vì vậy nó sẽ có thể làm một tìm kiếm lập chỉ mục trên cả hai dòng chữ "foo" và "barius", mà có thể có nhiều sử dụng

Đây là tài liệu cho rằng: https://docs.mongodb.com/manual/core/index-text/

Các vấn đề liên quan