Como consultar o MongoDB com "like"?


1437

Eu quero consultar algo com a likeconsulta do SQL :

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

Como faço para conseguir o mesmo no MongoDB? Não consigo encontrar um operador likena documentação .


7
consulte os documentos do mongodb: Consultas avançadas - Expressões regulares mongodb.org/display/DOCS/…
douyw

7
Sua pergunta tem pelo menos 5votos para a tag de operador like . Posso pedir que você sugira sql-like como sinônimo ?
Caco

3
Este link pode ajudá-lo (a) a goo.gl/gdTYK8
Dilip Kr Singh

Respostas:


1945

Isso teria que ser:

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

ou similar:

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

Você está procurando algo que contenha "m" em algum lugar (o %operador ' ' do SQL é equivalente ao ' .*' da Regexp ) ', não algo que tenha "m" ancorado no início da string.

nota: o mongodb usa expressões regulares que são mais poderosas que "LIKE" no sql. Com expressões regulares, você pode criar qualquer padrão que imaginar.

Para obter mais informações sobre expressões regulares, consulte este link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions


96
a pesquisa por regex é cara?
Freewind

147
Na verdade, depende. Se a consulta não usar um índice e precisar fazer uma varredura de tabela, certamente poderá ser caro. Se você estiver fazendo uma consulta regex 'começa com', isso poderá usar um índice. É melhor executar uma explicação () para ver o que está acontecendo.
Kyle Banker

35
Quando não está ancorado no início da string, é um pouco caro. Mas, novamente, o mesmo ocorre com uma LIKEconsulta no SQL.
Emily

4
desde que esteja ancorado no início da string, tudo bem? legal então. isso necessidade queremos dizer para adicionar ^
user4951

44
Gostaria de acrescentar 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%'

fora: paulo, patric

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

fora: paulo, patric

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

fora: pedro


bom exemplo! Eu estou achando final cheque com espaço e encontrei este :) / $ /
Phuong

como você encontra todas as entradas para o nome? ou o curinga para * no SQL? Algo que faz select name from users;que apenas lista todos os usuários?
anon58192932

1
@ anon58192932 Para exibir todas as entradas apenas do campo "nome" em uma tabela chamada "usuários", você pode usar o método project () definindo valores dos campos que deseja 1. Os campos que não são mencionados no projeto () não serão buscado, exceto _id. O campo _id é impresso por padrão, que você pode suprimir colocando 0 valor para o método _id dentro do projeto (). Algo como - db.collection.find (). Project ({name: 1, _id: 0}) .toArray (function (err, docs) {console.log (docs); callback (docs);}); Consulte isto - docs.mongodb.com/manual/tutorial/…
gauravparmar 15/02

282

No

  • PyMongo usando Python
  • Mongoose usando Node.js
  • Jongo , usando Java
  • mgo , usando Go

você pode fazer:

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

2
funciona bem para pesquisa com distinção entre maiúsculas e minúsculas, você poderia me dizer como posso fazê-lo funcionar para executar pesquisa sem distinção entre maiúsculas e minúsculas?
Tahir Yasin 29/03

Qual seria o regex para%sometext%
Tahir Yasin 30/03

64
@TahirYasin se você ainda está se perguntando, busca case-insensitive seria feito da seguinte forma:db.users.find({'name': {'$regex': 'sometext', '$options': 'i'}})
sumowrestler

Eu resolvidos em golang usando mgo simplesmente um código como este, seletor: = bson.M { "técnico": bson.M { "$ regex": tech}}
Sandun Priyanka

1
Sinto que esta deve ser a resposta aceita. É o mais simples e elegante atualmente.
Brett84c

88

No PHP, você pode usar o seguinte código:

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

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

1
Se o seu valor RegEx se origina da entrada do usuário (por exemplo, um formulário de filtro) e você não deseja que o próprio valor seja considerado como um RegExp, você deve aplicar preg_quote () a ele.
Philipp Rieber

2
Acabei de perceber isso, mas esta é realmente a resposta errada, mesmo que funcione abaixo do ideal, você deve usar o objeto regex BSON real via MongoRegex, $ regex tem problemas de compatibilidade com certos comandos como $ in
Sammaye

Esta sintaxe é útil se o valor é armazenado em uma variável, por isso, a consulta pode ser escrita como (em Ruby):$collection.where(field => {"$regex" => value})
Donny Kurnia

Mas por que você não pode usar literais de matriz?
Alper

53

Você usaria regex para isso no mongo.

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


29
Eu acho que isso só mostra documentos com um valor nome que começa com "m"
JackAce

53

Já existem muitas respostas. Estou fornecendo diferentes tipos de requisitos e soluções para pesquisa de strings com regex.

Você pode fazer com o regex que contém a palavra, por exemplo, like. Além disso, você pode usar $options => ipara pesquisa que não diferencia maiúsculas de minúsculas

Contém string

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

Não contém stringapenas regex

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

Insensível a maiúsculas e minúsculas string

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

Começar com string

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

Terminar com string

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

Mantenha isso como marcador e referência para quaisquer outras alterações que você possa precisar.


37

Você tem 2 opções:

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

ou

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

No segundo, você tem mais opções, como "i" nas opções para encontrar o uso de maiúsculas e minúsculas. E sobre a "string", você pode usar como ". String. " (% String%) ou "string. *" (String%) e ". * String) (% string), por exemplo. Você pode usar expressões regulares como você quiser.

Aproveitar!


34

Se você estiver usando o node.js , ele diz que você pode escrever isso:

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

Além disso , você pode escrever isso:

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

Sintaxe semelhante em Ruby:collection.where(field => Regexp.new(value))
Donny Kurnia 15/04

24

Você já conseguiu as respostas, mas para combinar regex com insensibilidade a maiúsculas e minúsculas

Você poderia usar a seguinte consulta

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

O ina /m/iindica caso insensibilidade e .pretty()fornece uma saída mais bonita


mas o que se eu quiser valor ajustado dinamicamente aqui
KS

@KuldeepKoranga você pode colocar qualquer valor dinâmico no lugar de 'm'. é isso que você quer.
The6thSense

var search="feacebook"então como posso definir abaixo @ The6thSens Sim, mas db.users.find ({ "name" : /search/i } )?
KS

@KuldeepKoranga você atribuiu o valor.
The6thSense

1
@KuldeepKoranga stackoverflow.com/questions/7790811/… isso ajuda?
The6thSense

18

Para Mongoose no Node.js

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

13

Você pode usar o novo recurso do 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
Observe que a pesquisa de texto do AFAIK Mongodb funciona em palavras inteiras apenas por padrão, portanto, isso corresponderá a valores como "Esta é uma string com texto", mas não "Esta é uma string com subtexto". Portanto, não é como o operador "LIKE" do sql.
Rocketmonkeys 10/03/2019

@Rocketmonkeys é verdade ... para algo como "LIKE operator", você usaria o operador $ regex mongo.
Cmarrero01

13

No nodejs project e use mongoose use 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);
            });

Como posso usar como consulta? Eu tentei isso, mas não está funcionando:searchQuery.product_name = '/'+req.query.search.value+'/i';
Muhammad Shahzad 10/10

pode tentar como:searchQuery.product_name= {$regex: req.query.search.value, $options: 'i'};
Shaishab Roy

Você salva minha vida, cara. você pode explicar pouco o que é $ regex e $ options?
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'}; }você pode ver por que isso não está funcionando?
Muhammad Shahzad

bem $regex: 'value' gerar expressão regular para o seu valor de pesquisa e $options: 'i'significa que não diferencia maiúsculas de minúsculas . Seu código não funcionou por causa do que você usou mesmo valor para a propriedade diferente e que atuam como e condição que não deve cumprir com sua coleção de banco de dados.
Shaishab Roy

12

Para o PHP mongo Like.
Eu tive vários problemas com o php mongo like. Eu descobri que concatenar os parâmetros do regex ajuda em algumas situações o PHP mongo find field começa com . Eu pensei em postar aqui para contribuir com o tópico mais popular

por exemplo

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)

Conforme respostas e comentários anteriores, a pesquisa $ text (Index) fornecerá uma solução melhor com o benchmark comparado ao método $ regex corretamente. Para referência, verifique este link stackoverflow.com/questions/10610131/… . É possível implementar $ método de índice de texto com PHP e mongoDB
sankar muniyappa

12

Usar literais de modelo com variáveis ​​também funciona:

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


Esta é uma pesquisa desde o início ex - se "firstname" contiver testlast e se eu pesquisar por "last" não dará resultado.
Vikas Chauhan

11

Com o MongoDB Compass, você precisa usar a sintaxe do modo estrito, como:

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

(No MongoDB Compass, é importante que você use em "vez de ')



10

No SQL, a consulta ' like ' é assim:

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

No console do MongoDB, fica assim:

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

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

Além disso pretty()método irá em todos os lugares onde produzir estrutura JSON formatada que é mais legível.


10

Regex são caros são processo.

Outra maneira é criar um índice de texto e pesquisá-lo usando $search.

Crie um índice de texto dos campos que você deseja tornar pesquisável:

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

Procure uma sequência no índice de texto:

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

Solução perfeita ... Regex's são muito caros. Trabalhando com um conjunto de dados de documentos de 20m e a diferença de desempenho é muito perceptível (que é um eufemismo)
nivensookharan

1
Na verdade, esta única funciona para palavras inteiras, consulte docs.mongodb.com/manual/core/index-text/#index-entries
Thomas Ebert

8

No Go e o driver mgo:

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

em que result é a instância struct do tipo procurado


2
pls evitar campos não codificadas em literais, que bson:RegEx{Pattern:"m", Options:"i"}em vez
bithavoc

8

Use expressões regulares correspondentes como abaixo. O 'i' mostra insensibilidade ao caso.

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

Como Query seria como mostrado abaixo

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

para 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

Parece que existem razões para usar o /regex_pattern/padrão javascript e o mongo {'$regex': 'regex_pattern'}. Consulte: Restrições de sintaxe MongoBD RegEx

Este não é um tutorial completo do RegEx, mas fui inspirado a executar esses testes depois de ver uma postagem ambígua altamente votada acima .

> ['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

Se você estiver usando o Spring-Data Mongodb, poderá fazer isso desta maneira:

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

4

Como o shell Mongo suporta regex, isso é completamente possível.

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

Se quisermos que a consulta não diferencie maiúsculas de minúsculas, podemos usar a opção "i", como mostrado abaixo:

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


4

Use a pesquisa de substring de agregação (com índice !!!):

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

agradável! existe uma maneira de combinar todo o documento? ou fazer a estrutura de agregação fazer uma consulta de acompanhamento para fazer isso? No momento, uma partida se parece com:{ "_id" : ObjectId("5aba5ad988385120a01b1ac2"), "fieldExists" : 4 }
Gianfranco P.

em $ fase de projecto apenas projetar o que você quer
Vokail

4

String 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

Encontrei uma ferramenta gratuita para traduzir consultas MYSQL para o MongoDB. http://www.querymongo.com/ Verifiquei com várias consultas. como eu vejo quase todos eles estão corretos. De acordo com isso, a resposta é

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

2

O MongoRegex foi preterido.
Use MongoDB \ BSON \ Regex

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

É importante notar que isso se refere à classe MongoRegex no PHP . Não é muito relevante para esta questão, que é sobre o Node. Provavelmente deve ser um comentário ou, melhor ainda, uma pergunta auto-respondida em um post separado.
Boaz - Restabelece Monica

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

Quando estamos pesquisando padrões de cadeia, sempre é melhor usar o padrão acima como quando não temos certeza sobre o caso. Espero que ajude!!!

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.