Thực hiện truy vấn regex với pymongo


129

Tôi đang cố gắng thực hiện một truy vấn regex bằng pymongo đối với máy chủ mongodb. Cấu trúc tài liệu như sau

{
  "files": [
    "File 1",
    "File 2",
    "File 3",
    "File 4"
  ],
  "rootFolder": "/Location/Of/Files"
}

Tôi muốn nhận tất cả các tệp phù hợp với mẫu * Tệp. Tôi đã thử làm điều này như vậy

db.collectionName.find({'files':'/^File/'})

Tuy nhiên, tôi không nhận được gì, tôi đang thiếu một cái gì đó bởi vì theo các tài liệu mongodb điều này là có thể. Nếu tôi thực hiện truy vấn trong bảng điều khiển mongo thì nó hoạt động tốt, điều này có nghĩa là api không hỗ trợ nó hay tôi chỉ sử dụng nó không đúng

Câu trả lời:


191

Nếu bạn muốn bao gồm các tùy chọn biểu thức chính quy (như trường hợp bỏ qua), hãy thử điều này:

import re
regx = re.compile("^foo", re.IGNORECASE)
db.users.find_one({"files": regx})

8
Cũng lưu ý rằng neo của regex khi bắt đầu (nghĩa là: bắt đầu bằng ^) có thể sử dụng các chỉ mục trong db và sẽ chạy nhanh hơn nhiều trong trường hợp đó.
drevicko

1
Regex bắt đầu bằng ^ chỉ có thể sử dụng một chỉ mục trong một số trường hợp nhất định . Khi sử dụng re.IGNORECASE, tôi tin rằng mongo không thể sử dụng một chỉ mục để thực hiện truy vấn.
nonagon

Việc sử dụng này được ghi nhận ở đâu đó? Tôi không thể tìm thấy điều này trong tài liệu API pymongo chính thức.
Hiếu

153

Hóa ra các tìm kiếm regex được thực hiện một chút khác nhau trong pymongo nhưng cũng dễ dàng như vậy.

Regex được thực hiện như sau:

db.collectionname.find({'files':{'$regex':'^File'}})

Điều này sẽ khớp với tất cả các tài liệu có thuộc tính tệp có một mục trong đó bắt đầu bằng Tệp


9
Trên thực tế, những gì bạn có ở đây cũng là cách nó được thực hiện trong javascript (và có lẽ các ngôn ngữ khác nữa) nếu bạn sử dụng $regex. Câu trả lời của @ Eric là cách trăn có chút khác biệt.
drevicko

có gì khác biệt? Cả hai đều sử dụng pymongo python đúng không? Đây là một phần của các truy vấn mongodb vì vậy tôi không thấy vấn đề thực sự.
Dexter

10
Ignorecase có thể có trong regex của mongodb JScript cũng viz. db.collectionname.find ({'files': {'$ regex': '^ Tệp', '$ tùy chọn': 'i'}})
Ajay Gupta

5
Câu trả lời này có vẻ tốt hơn trong mắt tôi. Tại sao phải biên dịch Python RE nếu bạn sắp xâu chuỗi nó để Mongo có thể biên dịch lại? $regexNhà điều hành của Mongo $optionstranh luận.
Đánh dấu E. Haase

3
Vui lòng sử dụng r'^File'thay vì '^File'để tránh vấn đề khác
Aminah Nuraini

9

Để tránh việc biên dịch kép, bạn có thể sử dụng trình bao bọc regex bson đi kèm với PyMongo:

>>> regx = bson.regex.Regex('^foo')
>>> db.users.find_one({"files": regx})

Regex chỉ lưu trữ chuỗi mà không cố biên dịch nó, vì vậy find_one sau đó có thể phát hiện đối số dưới dạng loại 'Regex' và tạo truy vấn Mongo thích hợp.

Tôi cảm thấy cách này hơi Pythonic hơn một chút so với câu trả lời hàng đầu khác, ví dụ:

>>> db.collectionname.find({'files':{'$regex':'^File'}})

Thật đáng để đọc tài liệu Regex bson nếu bạn định sử dụng truy vấn regex vì có một số cảnh báo.


1
Nếu bạn cần đối chiếu lại một mảng bằng $ in thì $ regex sẽ không hoạt động với bạn. bson.regex.Regex sẽ làm mánh khóe!
odedfos

4

Giải pháp rekhông sử dụng chỉ số nào cả. Bạn nên sử dụng các lệnh như:

db.collectionname.find({'files':{'$regex':'^File'}})

(Tôi không thể bình luận bên dưới câu trả lời của họ, vì vậy tôi trả lời ở đây)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.