Làm thế nào để truy vấn MongoDB với bản quyền như trực tuyến?


1437

Tôi muốn truy vấn một cái gì đó với liketruy vấn của SQL :

SELECT * FROM users  WHERE name LIKE '%m%'

Làm cách nào để tôi đạt được điều tương tự trong MongoDB? Tôi không thể tìm thấy một nhà điều hành liketrong tài liệu .


7
xem tài liệu của mongodb: Truy vấn nâng cao - Biểu thức chính quy mongodb.org/display/DOCS/iêu
douyw

7
Câu hỏi của bạn có ít nhất 5phiếu bầu cho thẻ nhà điều hành tương tự . Tôi có thể vui lòng yêu cầu bạn đề xuất như sql như một từ đồng nghĩa không?
Kermit

3
Liên kết này có thể giúp bạn goo.gl/gdTYK8
Dilip Kr Singh

Câu trả lời:


1945

Đó sẽ phải là:

db.users.find({"name": /.*m.*/})

hoặc tương tự:

db.users.find({"name": /m/})

Bạn đang tìm kiếm thứ gì đó có chứa "m" ở đâu đó ( %toán tử ' ' của SQL tương đương với Regapi ' .*'), không phải thứ gì đó có "m" được neo vào đầu chuỗi.

lưu ý: mongodb sử dụng các biểu thức chính quy mạnh hơn "THÍCH" trong sql. Với các biểu thức thông thường, bạn có thể tạo bất kỳ mẫu nào mà bạn tưởng tượng.

Để biết thêm thông tin về các biểu thức thông thường, hãy tham khảo liên kết này https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions


96
Tìm kiếm bằng regex có đắt không?
Freewind

147
Trên thực tế, nó phụ thuộc. Nếu truy vấn không sử dụng một chỉ mục và phải thực hiện quét bảng, thì nó chắc chắn có thể tốn kém. Nếu bạn đang thực hiện một truy vấn regex 'bắt đầu với', thì điều đó có thể sử dụng một chỉ mục. Tốt nhất để chạy một giải thích () để xem những gì đang xảy ra.
Kyle Banker

35
Khi không được neo vào đầu chuỗi, nó có phần đắt tiền. Nhưng sau đó, một lần nữa, một LIKEtruy vấn trong SQL.
Emily

4
miễn là nó được neo vào đầu chuỗi thì không sao? mát mẻ sau đó. điều đó có nghĩa là chúng ta cần thêm ^
user4951

44
Tôi sẽ thêm regex ijavascript db.users.find({ "name": { $regex: /m/i } })
Doron Segal

368
db.users.insert({name: 'paulo'})
db.users.insert({name: 'patric'})
db.users.insert({name: 'pedro'})

db.users.find({name: /a/})  //like '%a%'

ra: paulo, patric

db.users.find({name: /^pa/}) //like 'pa%' 

ra: paulo, patric

db.users.find({name: /ro$/}) //like '%ro'

ra: bàn đạp


ví dụ tốt đẹp Tôi đang tìm kiếm kết thúc kiểm tra với không gian và tìm thấy cái này :) / $ /
Phương

Làm thế nào để bạn tìm thấy tất cả các mục cho tên? hoặc ký tự đại diện cho * trong SQL? Một cái gì đó select name from users;mà chỉ liệt kê tất cả người dùng?
anon58192932

1
@ anon58192932 Để hiển thị tất cả các mục nhập của trường "name" trong bảng có tên "users", bạn có thể sử dụng phương thức project () bằng cách đặt giá trị của các trường mà bạn muốn 1. Các trường không được đề cập trong dự án () sẽ không lấy ngoại trừ _id. Trường _id được in theo mặc định mà bạn có thể triệt tiêu bằng cách đặt 0 giá trị cho phương thức _id bên trong dự án (). Một cái gì đó như - db.collection.find (). Project ({name: 1, _id: 0}) .toArray (function (err, docs) {console.log (docs); callback (docs);}); Tham khảo điều này - docs.mongodb.com/manual/tutorial/ từ
gauravparmar

282

Trong

  • PyMongo sử dụng Python
  • Mongoose sử dụng Node.js
  • Jongo , sử dụng Java
  • mgo , sử dụng Go

bạn có thể làm:

db.users.find({'name': {'$regex': 'sometext'}})

2
nó hoạt động tốt cho tìm kiếm phân biệt chữ hoa chữ thường, bạn có thể vui lòng cho tôi biết làm thế nào tôi có thể làm cho nó hoạt động để thực hiện tìm kiếm không phân biệt chữ hoa chữ thường không?
Tahir Yasin

Điều gì sẽ là biểu tượng cho%sometext%
Tahir Yasin

64
@TahirYasin nếu bạn vẫn đang tự hỏi, tìm kiếm không phân biệt chữ hoa chữ thường sẽ được thực hiện như sau:db.users.find({'name': {'$regex': 'sometext', '$options': 'i'}})
sumowrestler

Tôi đã giải quyết bằng golang bằng cách sử dụng mã mgo đơn giản như thế này, bộ chọn: = bson.M {"kỹ thuật viên": bson.M {"$ regex": tech}}
Sandun Priyanka

1
Cảm thấy như thế này nên là câu trả lời được chấp nhận. Đó là đơn giản và thanh lịch nhất hiện nay.
Brett84c

88

Trong PHP, bạn có thể sử dụng mã sau đây:

$collection->find(array('name'=> array('$regex' => 'm'));

4
python + mongoengine: people = People.objects.raw_query ({'name': {'$ regex': 'm'}})
panchicore

1
Nếu giá trị RegEx của bạn bắt nguồn từ đầu vào của người dùng (ví dụ: dạng bộ lọc) và bạn không muốn giá trị đó được lấy làm RegExp, bạn có thể nên áp dụng preg_quote () cho nó.
Philipp Rieber

2
Tôi mới nhận ra điều này, nhưng đây thực sự là câu trả lời sai, mặc dù nó hoạt động không tối ưu, thay vào đó bạn nên sử dụng đối tượng regex BSON thực tế thông qua MongoRegex, $ regex có vấn đề tương thích với một số lệnh nhất định như $ in
Sammaye

Cú pháp này hữu ích nếu giá trị được lưu trữ trong một biến, vì vậy truy vấn có thể được viết dưới dạng (trong Ruby):$collection.where(field => {"$regex" => value})
Donny Kurnia

Nhưng tại sao bạn không thể sử dụng mảng chữ?
Alper

53

Bạn sẽ sử dụng regex cho điều đó trong mongo.

ví dụ: db.users.find({"name": /^m/})


29
Tôi nghĩ rằng điều này chỉ hiển thị các tài liệu có giá trị tên bắt đầu bằng "m"
JackAce

53

Đã có nhiều câu trả lời. Tôi đang đưa ra các loại yêu cầu và giải pháp khác nhau cho tìm kiếm chuỗi với regex.

Bạn có thể làm với regex có chứa từ tức là thích. Ngoài ra, bạn có thể sử dụng $options => icho trường hợp tìm kiếm không nhạy cảm

Chứa đựng string

db.collection.find({name:{'$regex' : 'string', '$options' : 'i'}})

Không stringchỉ chứa với regex

db.collection.find({name:{'$regex' : '^((?!string).)*$', '$options' : 'i'}})

Trường hợp chính xác không nhạy cảm string

db.collection.find({name:{'$regex' : '^string$', '$options' : 'i'}})

Bắt đầu với string

db.collection.find({name:{'$regex' : '^string', '$options' : 'i'}})

Kết thúc với string

db.collection.find({name:{'$regex' : 'string$', '$options' : 'i'}})

Giữ như một dấu trang và một tài liệu tham khảo cho bất kỳ thay đổi nào khác mà bạn có thể cần.


37

Bạn có 2 sự lựa chọn:

db.users.find({"name": /string/})

hoặc là

db.users.find({"name": {"$regex": "string", "$options": "i"}})

Trong lần thứ hai, bạn có nhiều tùy chọn hơn, như "i" trong các tùy chọn để tìm cách sử dụng trường hợp không nhạy cảm. Và về "chuỗi", bạn có thể sử dụng như ". Chuỗi. " (% Chuỗi%) hoặc "chuỗi. *" (Chuỗi%) và ". * Chuỗi) (% chuỗi) chẳng hạn. Bạn có thể sử dụng biểu thức chính quy như bạn muốn.

Thưởng thức!


34

Nếu sử dụng node.js , nói rằng bạn có thể viết điều này:

db.collection.find( { field: /acme.*corp/i } );
//or
db.collection.find( { field: { $regex: 'acme.*corp', $options: 'i' } } );

Ngoài ra , bạn có thể viết điều này:

db.collection.find( { field: new RegExp('acme.*corp', 'i') } );

Cú pháp tương tự trong Ruby:collection.where(field => Regexp.new(value))
Donny Kurnia

24

Bạn đã có câu trả lời nhưng để phù hợp với regex với trường hợp không nhạy cảm

Bạn có thể sử dụng truy vấn sau đây

db.users.find ({ "name" : /m/i } ).pretty()

Các itrong /m/ichỉ ra trường hợp vô hồn và .pretty()cung cấp một sản lượng khá hơn


nhưng điều gì sẽ xảy ra nếu tôi muốn thiết lập giá trị động ở đây
KS

@KuldeepKoranga bạn có thể đặt bất kỳ giá trị động nào thay cho 'm'. đó là điều bạn muốn.
The6thSense

var search="feacebook"vậy làm thế nào tôi có thể thiết lập bên dưới @ The6thSens Có, nhưng db.users.find ({ "name" : /search/i } )?
KS

@KuldeepKoranga bạn đã gán giá trị.
The6thSense

1
@KuldeepKoranga stackoverflow.com/questions/7790811/ từ thực hiện trợ giúp này
The6thSense

18

Dành cho Mongoose trong Node.js

db.users.find({'name': {'$regex': '.*sometext.*'}})

13

Bạn có thể sử dụng tính năng mới của 2.6 mongodb:

db.foo.insert({desc: "This is a string with text"});
db.foo.insert({desc:"This is a another string with Text"});
db.foo.ensureIndex({"desc":"text"});
db.foo.find({
    $text:{
        $search:"text"
    }
});

6
Lưu ý, tìm kiếm văn bản của AFAIK Mongodb chỉ hoạt động trên toàn bộ các từ, do đó, điều này sẽ khớp với các giá trị như "Đây là một chuỗi có văn bản", nhưng không phải "Đây là một chuỗi có ẩn ý". Vì vậy, nó không hoàn toàn giống như toán tử "THÍCH" của sql.
lửa

@Rocketmonkeys đúng như vậy .. đối với một cái gì đó như "Toán tử THÍCH", bạn sẽ sử dụng toán tử $ regex mongo.
cmarrero01

13

Trong dự án nodejs và sử dụng mongoose sử dụng Like query

var User = mongoose.model('User');

var searchQuery={};
searchQuery.email = req.query.email;
searchQuery.name = {$regex: req.query.name, $options: 'i'};
User.find(searchQuery, function(error, user) {
                if(error || user === null) {
                    return res.status(500).send(error);
                }
                return res.status(200).send(user);
            });

Làm thế nào tôi có thể sử dụng như truy vấn? Tôi đã thử cách này nhưng không hoạt động:searchQuery.product_name = '/'+req.query.search.value+'/i';
Muhammad Shahzad

có thể thử như:searchQuery.product_name= {$regex: req.query.search.value, $options: 'i'};
Shaishab Roy

Bạn cứu mạng anh bạn. bạn có thể vui lòng giải thích chút ít tùy chọn $ regex và $ là gì không?
Muhammad Shahzad

if(req.query.search.value){ searchQuery.product_name = {$regex: req.query.search.value, $options: 'i'}; searchQuery.sale_amount = {$regex: req.query.search.value, $options: 'i'}; searchQuery.sale_person = {$regex: req.query.search.value, $options: 'i'}; searchQuery.department_name = {$regex: req.query.search.value, $options: 'i'}; searchQuery.sale_date = {$regex: req.query.search.value, $options: 'i'}; }bạn có thể xin vui lòng xem tại sao điều này không làm việc?
Muhammad Shahzad

cũng $regex: 'value' tạo biểu thức chính quy cho giá trị tìm kiếm của bạn và $options: 'i'có nghĩa là trường hợp không nhạy cảm . Mã của bạn không hoạt động vì bạn đã sử dụng cùng một giá trị cho các thuộc tính khác nhau và điều đó hoạt động như điều kiện không nên đáp ứng với bộ sưu tập cơ sở dữ liệu của bạn.
Shaishab Roy

12

Dành cho PHP mongo Like.
Tôi đã có một số vấn đề với php mongo như thế nào. tôi thấy rằng việc kết hợp các tham số regex sẽ giúp trong một số trường hợp PHP mongo tìm trường bắt đầu bằng . Tôi hình dung tôi sẽ đăng lên đây để đóng góp cho chủ đề phổ biến hơn

ví dụ

db()->users->insert(['name' => 'john']);
db()->users->insert(['name' => 'joe']);
db()->users->insert(['name' => 'jason']);

// starts with
$like_var = 'jo';
$prefix = '/^';
$suffix = '/';
$name = $prefix . $like_var . $suffix;
db()->users->find(['name' => array('$regex'=>new MongoRegex($name))]);
output: (joe, john)

// contains
$like_var = 'j';
$prefix = '/';
$suffix = '/';
$name = $prefix . $like_var . $suffix;
db()->users->find(['name' => array('$regex'=>new MongoRegex($name))]);

output: (joe, john, jason)

Theo câu trả lời và nhận xét trước đó, tìm kiếm $ text (Index) sẽ đưa ra giải pháp tốt hơn với điểm chuẩn so với phương pháp $ regex ngay. Để tham khảo, hãy kiểm tra liên kết này stackoverflow.com/questions/10610131/ . Có thể triển khai phương thức chỉ mục văn bản $ với PHP và mongoDB
sankar muniyappa

12

Sử dụng mẫu chữ với các biến cũng hoạt động:

{"firstname": {$regex : `^${req.body.firstname}.*` , $options: 'si' }}


Đây là searchig từ bắt đầu ex - nếu "Firstname" chứa testlast và nếu tôi tìm kiếm theo "last" thì nó sẽ không cho kết quả.
Vikas Chauhan

11

Với MongoDB Compass, bạn cần sử dụng cú pháp chế độ nghiêm ngặt, như sau:

{ "text": { "$regex": "^Foo.*", "$options": "i" } }

(Trong MongoDB La bàn, điều quan trọng là bạn sử dụng "thay vì ')



10

Trong SQL, truy vấn ' like ' trông như thế này:

select * from users where name like '%m%'

Trong bảng điều khiển MongoDB, nó trông như thế này:

db.users.find({"name": /m/})     // Not JSON formatted

db.users.find({"name": /m/}).pretty()  // JSON formatted

Trong pretty()phương thức bổ sung sẽ ở tất cả những nơi tạo ra cấu trúc JSON được định dạng dễ đọc hơn.


10

Regex đắt tiền là quá trình.

Một cách khác là tạo một chỉ mục của văn bản và sau đó tìm kiếm nó bằng cách sử dụng $search.

Tạo một văn bản Chỉ mục các trường bạn muốn làm cho có thể tìm kiếm:

db.collection.createIndex({name: 'text', otherField: 'text'});

Tìm kiếm một chuỗi trong chỉ mục văn bản:

db.collection.find({
  '$text'=>{'$search': "The string"}
})

Giải pháp hoàn hảo ... Regex là cách đắt đỏ. Làm việc với bộ dữ liệu gồm 20m tài liệu và sự khác biệt về hiệu suất là rất đáng chú ý (đó là một cách đánh giá thấp)
nivensookharan

1
Thật vậy, điều này chỉ hoạt động cho toàn bộ các từ, xem docs.mongodb.com/manual/core/index-text/#index-entries
Thomas Ebert

8

Trong Go và trình điều khiển mgo:

Collection.Find(bson.M{"name": bson.RegEx{"m", ""}}).All(&result)

trong đó kết quả là thể hiện cấu trúc của kiểu tìm kiếm


2
vui lòng tránh các trường không khóa trong chữ, bson:RegEx{Pattern:"m", Options:"i"}thay vào đó
bithavoc

8

Sử dụng biểu thức chính quy phù hợp như dưới đây. 'I' cho thấy trường hợp không nhạy cảm.

var collections = mongoDatabase.GetCollection("Abcd");

var queryA = Query.And(
         Query.Matches("strName", new BsonRegularExpression("ABCD", "i")), 
         Query.Matches("strVal", new BsonRegularExpression("4121", "i")));

var queryB = Query.Or(
       Query.Matches("strName", new BsonRegularExpression("ABCD","i")),
       Query.Matches("strVal", new BsonRegularExpression("33156", "i")));

var getA = collections.Find(queryA);
var getB = collections.Find(queryB);

6

Like Query sẽ như dưới đây

db.movies.find({title: /.*Twelve Monkeys.*/}).sort({regularizedCorRelation : 1}).limit(10);

cho scala ReactiveMongo api,

val query = BSONDocument("title" -> BSONRegex(".*"+name+".*", "")) //like
val sortQ = BSONDocument("regularizedCorRelation" -> BSONInteger(1))
val cursor = collection.find(query).sort(sortQ).options(QueryOpts().batchSize(10)).cursor[BSONDocument]

6

Dường như có nhiều lý do để sử dụng cả /regex_pattern/mẫu javascript cũng như {'$regex': 'regex_pattern'}mẫu mongo . Xem: Giới hạn cú pháp MongoBD RegEx

Đây không phải là một hướng dẫn RegEx hoàn chỉnh, nhưng tôi được truyền cảm hứng để chạy các bài kiểm tra này sau khi thấy một bài viết mơ hồ được bình chọn cao ở trên .

> ['abbbb','bbabb','bbbba'].forEach(function(v){db.test_collection.insert({val: v})})

> db.test_collection.find({val: /a/})
{ "val" : "abbbb" }
{ "val" : "bbabb" }
{ "val" : "bbbba" }

> db.test_collection.find({val: /.*a.*/})
{ "val" : "abbbb" }
{ "val" : "bbabb" }
{ "val" : "bbbba" }

> db.test_collection.find({val: /.+a.+/})
{ "val" : "bbabb" }

> db.test_collection.find({val: /^a/})
{ "val" : "abbbb" }

> db.test_collection.find({val: /a$/})
{ "val" : "bbbba" }

> db.test_collection.find({val: {'$regex': 'a$'}})
{ "val" : "bbbba" }

5

Nếu bạn đang sử dụng Spring-Data Mongodb Bạn có thể làm điều này theo cách này:

String tagName = "m";
Query query = new Query();
query.limit(10);        
query.addCriteria(Criteria.where("tagName").regex(tagName));

4

Vì vỏ Mongo hỗ trợ regex, điều đó hoàn toàn có thể.

db.users.findOne({"name" : /.*sometext.*/});

Nếu chúng tôi muốn truy vấn không phân biệt chữ hoa chữ thường, chúng tôi có thể sử dụng tùy chọn "i", như hiển thị bên dưới:

db.users.findOne({"name" : /.*sometext.*/i});


4

Sử dụng tìm kiếm chuỗi con tổng hợp (có chỉ mục !!!):

db.collection.aggregate([{
        $project : {
            fieldExists : {
                $indexOfBytes : ['$field', 'string']
            }
        }
    }, {
        $match : {
            fieldExists : {
                $gt : -1
            }
        }
    }, {
        $limit : 5
    }
]);

đẹp! Có cách nào để có được toàn bộ tài liệu phù hợp? hoặc làm cho khung tổng hợp thực hiện một truy vấn tiếp theo để làm điều đó? Tại thời điểm một trận đấu trông giống như:{ "_id" : ObjectId("5aba5ad988385120a01b1ac2"), "fieldExists" : 4 }
Gianfranco P.

trong giai đoạn dự án $ chỉ cần dự án những gì bạn muốn
Vokail

4

Chuỗi deepakparmar, dipak, parmar

db.getCollection('yourdb').find({"name":/^dee/})

ans Deepakparmar

db.getCollection('yourdb').find({"name":/d/})

ans Deepakparmar, dipak

db.getCollection('yourdb').find({"name":/mar$/})

ans Deepakparmar, parmar


2

Tôi tìm thấy một công cụ miễn phí để dịch các truy vấn MYSQL sang MongoDB. http://www.querymongo.com/ Tôi đã kiểm tra với một số truy vấn. như tôi thấy hầu hết tất cả đều đúng Theo đó, câu trả lời là

db.users.find({
    "name": "%m%"
});

2

MongoRegex đã bị phản đối.
Sử dụng MongoDB \ BSON \ Regex

$regex = new MongoDB\BSON\Regex ( '^m');
$cursor = $collection->find(array('users' => $regex));
//iterate through the cursor

Điều quan trọng cần lưu ý là điều này đề cập đến lớp MongoRegex trong PHP . Không liên quan lắm đến câu hỏi này là về Node. Đây có lẽ nên là một bình luận hoặc tốt hơn - một câu hỏi tự trả lời trong bài riêng biệt.
Boaz - Tái lập Monica

2
db.customer.find({"customerid": {"$regex": "CU_00000*", "$options": "i"}}).pretty()

Khi chúng tôi đang tìm kiếm các mẫu chuỗi, luôn luôn tốt hơn là sử dụng mẫu trên như khi chúng tôi không chắc chắn về trường hợp. Mong rằng sẽ giúp !!!

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.