$regex
và MongoRegex (tức là loại regex BSON được sử dụng trong đối sánh bình đẳng) chỉ hỗ trợ đối sánh với các chuỗi, vì vậy bạn không thể sử dụng chúng trực tiếp với ObjectId.
Về ví dụ mã cuối cùng của bạn, bạn đã cố sử dụng $where
trong một phương thức khởi tạo MongoRegex:
$searchTermsAny[] = array(
$dataProps[$i] => new MongoRegex( '/'.$sRegex.'/i',
'$where: "this._id.toString().match(/'.$sRegex.'/i)"' )
);
MongoRegex
Hàm tạo của có một chuỗi đơn (ví dụ:/foo/i
), từ đó nó suy ra mẫu và cờ. $where
được dự định sử dụng như một toán tử truy vấn cấp cao nhất (không được liên kết với bất kỳ tên trường nào). Tôi không làm theo những gì bạn đang làm với $dataProps[$i]
, nhưng giả sử bạn đang tạo một $where
truy vấn để khớp với biểu diễn chuỗi của ObjectId. Tài liệu truy vấn sẽ giống như sau:
{ $where: 'this._id.str.match(/00005/)' }
Lưu ý rằng tôi đang truy cập str
ở đây thay vì gọi toString()
. Đó là bởi vì toString()
thực sự trả về biểu diễn shell của ObjectId. Bạn có thể thấy điều này bằng cách kiểm tra nguồn của nó trong shell:
> x = new ObjectId()
ObjectId("5409ddcfd95d6f6a2eb33e7f")
> x.toString
function (){
return "ObjectId(" + tojson(this.str) + ")";
}
Ngoài ra, nếu bạn chỉ đơn giản là kiểm tra xem một chuỗi con có tồn tại trong _id
hay không biểu diễn hex của, bạn có thể muốn sử dụng indexOf()
(với != -1
so sánh) thay vì match()
với một regex.
Điều đó nói rằng, bằng cách sử dụng $where
nói chung là một ý tưởng tồi nếu bạn không kết hợp nó với các tiêu chí truy vấn bổ sung mà có thể sử dụng một chỉ mục. Điều này là do $where
gọi trình thông dịch JavaScript cho mỗi tài liệu được xem xét trong tập kết quả. Nếu bạn kết hợp nó với các tiêu chí khác, chọn lọc hơn, MongoDB có thể sử dụng một chỉ mục và thu hẹp các tài liệu mà nó cần để đánh giá với $where
; tuy nhiên, bạn đang ở trong một khoảng thời gian tồi tệ nếu bạn đang sử dụng $where
và quét nhiều tài liệu hoặc quét bảng trong trường hợp xấu nhất.
Có lẽ bạn nên tạo trường thứ hai trong mỗi tài liệu chứa biểu diễn chuỗi hex của _id
. Sau đó, bạn có thể lập chỉ mục trường đó và truy vấn trường đó bằng cách sử dụng regex. Các truy vấn regex không được cố định sẽ vẫn hơi kém hiệu quả (xem: sử dụng chỉ mục regex
trong tài liệu), nhưng điều này vẫn sẽ nhanh hơn nhiều so với việc sử dụng $where
.
Giải pháp này (sao chép _id
string) sẽ phải chịu thêm một số dung lượng lưu trữ trên mỗi tài liệu, nhưng bạn có thể quyết định rằng 24-30 byte bổ sung (tải trọng chuỗi và tên trường ngắn) là không đáng kể.