Pymongo ile normal ifade sorguları gerçekleştirme


129

Bir mongodb sunucusuna karşı pymongo kullanarak bir regex sorgusu yapmaya çalışıyorum. Belge yapısı aşağıdaki gibidir

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

* Dosya kalıbı ile eşleşen tüm dosyaları almak istiyorum. Bunu böyle yapmayı denedim

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

Yine de hiçbir şeyi geri alamıyorum, bir şeyi mi kaçırıyorum çünkü mongodb belgelerine göre bu mümkün olmalı. Sorguyu mongo konsolunda gerçekleştirirsem iyi çalışıyor, bu api'nin onu desteklemediği anlamına mı geliyor yoksa sadece yanlış mı kullanıyorum

Yanıtlar:


191

Normal ifade seçeneklerini dahil etmek istiyorsanız (büyük / küçük harf kullanımını göz ardı etme gibi), şunu deneyin:

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

8
Ayrıca, başlangıçta sabitlenen (yani: ile başlayarak ^) normal ifadelerin db'deki dizinleri kullanabileceğini ve bu durumda çok daha hızlı çalışacağını unutmayın.
drevicko

1
Normal ifadelerin ^ ile başlaması yalnızca belirli durumlarda bir dizin kullanabilir . Re.IGNORECASE kullanırken, mongo'nun sorguyu gerçekleştirmek için bir indeks kullanamayacağına inanıyorum.
nonagon

Bu kullanım bir yerde belgelenmiş mi? Bunu resmi pymongo API belgesinde bulamıyorum.
Hieu

153

Normal ifade aramalarının pymongo'da biraz farklı yapıldığı, ancak bu kadar kolay olduğu ortaya çıktı.

Regex şu şekilde yapılır:

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

Bu, içinde File ile başlayan bir öğe içeren bir files özelliğine sahip tüm belgelerle eşleşir.


9
Aslında burada sahip olduğunuz şey, kullanırsanız javascript'te (ve muhtemelen diğer dillerde de) yapılma şeklidir$regex . @ Eric'in cevabı biraz farklı olan python yolu.
drevicko

fark ne? İkisi de python pymongo kullanıyor mu? Bu, mongodb sorgularının bir parçası, bu yüzden sorunu gerçekten görmüyorum.
Dexter

10
Yoksayma mongodb JScript'in regex'inde de mümkündür. db.collectionname.find ({'files': {'$ regex': '^ Dosya', '$ seçenekler': 'i'}})
Ajay Gupta

5
Bu cevap gözlerime daha iyi görünüyor. Mongo'nun tekrar derleyebilmesi için onu dizgilendirecekseniz neden bir Python RE derlemeye uğraşasınız ki? Mongo'nun $regexoperatörü tartışır $options.
Mark E. Haase

3
Lütfen başka sorunlardan kaçınmak için r'^File'yerine kullanın'^File'
Aminah Nuraini

9

Çift derlemeden kaçınmak için PyMongo ile birlikte gelen bson normal ifade sarmalayıcısını kullanabilirsiniz:

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

Regex dizeyi derlemeye çalışmadan depolar, böylece find_one daha sonra argümanı bir 'Regex' türü olarak algılayabilir ve uygun Mongo sorgusunu oluşturabilir.

Bu yolun diğer en iyi cevaptan biraz daha fazla Pythonic olduğunu düşünüyorum, örneğin:

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

Normal ifade sorgularını kullanmayı planlıyorsanız, bazı uyarılar olduğundan bson Regex belgelerini okumaya değer.


1
$ İn kullanarak bir diziyi tekrar eşleştirmeniz gerekiyorsa, $ regex sizin için çalışmayacaktır. bson.regex.Regex hile yapacak!
odedfos

4

Çözümü redizini hiç kullanmıyor. Aşağıdaki gibi komutlar kullanmalısınız:

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

(Cevaplarının altına yorum yapamam, bu yüzden burada cevap veriyorum)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.