Przykład:
> db.stuff.save({"foo":"bar"});
> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
mongodb
case-insensitive
Luke Dennis
źródło
źródło
$caseSensitive: false
. Zobacz: docs.mongodb.org/manual/reference/operator/query/text/…$caseSensitive
jest fałszem i to nie odpowiada na pytanie, ponieważ działa tylko na indeksowanych polach. OP szukał porównania ciągów bez rozróżniania wielkości liter.Odpowiedzi:
Możesz użyć wyrażenia regularnego .
W twoim przykładzie byłoby to:
Muszę jednak powiedzieć, że może po prostu zmniejszysz wartość (lub zwiększysz) wartość po drodze, zamiast ponosić dodatkowy koszt za każdym razem, gdy ją znajdziesz. Oczywiście nie zadziała to w przypadku nazwisk osób i tym podobnych, ale może przypadków użycia takich jak tagi.
źródło
AKTUALIZACJA:
Oryginalna odpowiedź jest już nieaktualna. Mongodb obsługuje teraz zaawansowane wyszukiwanie pełnotekstowe z wieloma funkcjami.
ORYGINALNA ODPOWIEDŹ:
Należy zauważyć, że wyszukiwanie z rozróżnianiem wielkości liter w wyrażeniach regularnych / i oznacza, że mongodb nie może wyszukiwać według indeksu, więc zapytania do dużych zestawów danych mogą zająć dużo czasu.
Nawet przy małych zestawach danych nie jest to zbyt wydajne. Przyjmujesz znacznie większą moc procesora niż twoje zapytanie, co może stać się problemem, jeśli próbujesz osiągnąć skalę.
Alternatywnie możesz przechowywać wielką kopię i wyszukiwać według niej. Na przykład mam tabelę użytkowników, która ma nazwę użytkownika, która jest wielkimi literami, ale identyfikator jest wielką literą nazwy użytkownika. Zapewnia to, że powielanie z rozróżnianiem wielkości liter jest niemożliwe (nie można zarówno używać „Foo”, jak i „foo”), i mogę wyszukiwać według id = nazwa_użytkownika.toUpperCase (), aby uzyskać wyszukiwanie nazwy użytkownika bez rozróżniania wielkości liter.
Jeśli twoje pole jest duże, na przykład treść wiadomości, powielanie danych prawdopodobnie nie jest dobrym rozwiązaniem. Uważam, że użycie zewnętrznego indeksatora, takiego jak Apache Lucene, jest najlepszą opcją w tym przypadku.
źródło
username: 'bill'
dopasowanieBILL
lubBill
nie kwerendy wyszukiwania pełnotekstowego, która będzie również mecz wynikała słowa obill
, takie jakBills
,billed
itd.Jeśli chcesz utworzyć wyrażenie regularne ze zmiennej, jest to o wiele lepszy sposób: https://stackoverflow.com/a/10728069/309514
Następnie możesz zrobić coś takiego:
Ma to tę zaletę, że jest bardziej programowy lub możesz zwiększyć wydajność, kompilując go wcześniej, jeśli często go używasz.
źródło
new RegExp("^" + req.params.term.toLowerCase(), "i")
działa również dobrzePamiętaj, że poprzedni przykład:
spowoduje, że wszystkie wpisy zawierające pasek będą pasować do zapytania (bar1, barxyz, openbar), może być bardzo niebezpieczne dla wyszukiwania nazwy użytkownika w funkcji auth ...
Może być konieczne dopasowanie go tylko do wyszukiwanego hasła przy użyciu odpowiedniej składni wyrażenia regularnego jako:
Zobacz http://www.regular-expressions.info/, aby uzyskać pomoc dotyczącą składni wyrażeń regularnych
źródło
Począwszy od MongoDB 3.4, zalecanym sposobem szybkiego wyszukiwania bez rozróżniania wielkości liter jest użycie indeksu bez rozróżniania wielkości liter .
Osobiście wysłałem e-maila do jednego z założycieli, aby ten działał, a on to sprawił! To był problem na JIRA od 2009 roku i wielu poprosiło o tę funkcję. Oto jak to działa:
Indeks bez rozróżniania wielkości liter jest tworzony przez określenie sortowania o sile 1 lub 2. Można utworzyć indeks bez rozróżniania wielkości liter, jak poniżej:
Możesz także określić domyślne sortowanie dla kolekcji podczas ich tworzenia:
W obu przypadkach, aby użyć indeksu bez rozróżniania wielkości liter, musisz określić to samo sortowanie w
find
operacji, która była używana podczas tworzenia indeksu lub kolekcji:Zwróci „Nowy Jork”, „Nowy Jork”, „Nowy Jork” itp.
Inne notatki
username: 'bill'
dopasowanieBILL
lubBill
, a nie kwerendy wyszukiwanie pełnotekstowe, które również mecz wynikała słowabill
, takie jakBills
,billed
etc.Odpowiedzi sugerujące użycie wyrażeń regularnych są powolne, ponieważ nawet przy indeksach dokumentacja stwierdza :
$regex
odpowiedzi również narażają na ryzyko wprowadzenia danych przez użytkownika .źródło
źródło
TL; DR
Prawidłowy sposób na zrobienie tego w mongo
Nie używaj RegExp
Stań się naturalny I użyj wbudowanego indeksowania mongodb, szukaj
Krok 1 :
Krok 2 :
Musisz utworzyć indeks w dowolnym polu tekstowym, które chcesz przeszukać, bez zapytania o indeksowanie będzie to bardzo powolne
krok 3 :
źródło
username: 'bill'
dopasowanieBILL
lubBill
nie kwerendy wyszukiwania pełnotekstowego, która będzie również mecz wynikała słowa obill
, takie jakBills
,billed
itd.źródło
$existing = Users::masterFind('all', ['conditions' => ['traits.0.email' => ['$regex' => "^$value$", '$options' => 'i']]]);
Mongo (aktualna wersja 2.0.0) nie zezwala na wyszukiwanie bez rozróżniania wielkości liter względem indeksowanych pól - zobacz ich dokumentację . W przypadku pól nieindeksowanych wyrażenia regularne wymienione w innych odpowiedziach powinny być w porządku.
źródło
Podczas korzystania z zapytania opartego na Regex należy pamiętać o jednej bardzo ważnej rzeczy - robiąc to dla systemu logowania, unikaj każdego szukanego znaku i nie zapomnij o operatorach ^ i $. Lodash ma do tego przyjemną funkcję , jeśli już z niej korzystasz:
Dlaczego? Wyobraź sobie użytkownika wprowadzającego się
.*
jako jego nazwa użytkownika. To by pasowało do wszystkich nazw użytkowników, umożliwiając logowanie po prostu odgadując hasło dowolnego użytkownika.źródło
Najlepsza metoda jest w wybranym języku, podczas tworzenia opakowania modelu dla twoich obiektów, niech twoja metoda save () iteruje przez zestaw pól, które będziesz przeszukiwał i które są również indeksowane; zestaw pól powinien zawierać małe litery, które są następnie używane do wyszukiwania.
Za każdym razem, gdy obiekt jest zapisywany, właściwości małych liter są następnie sprawdzane i aktualizowane o wszelkie zmiany w głównych właściwościach. To sprawi, że będziesz mógł efektywnie wyszukiwać, ale ukryjesz dodatkową pracę potrzebną do aktualizacji pól lc za każdym razem.
Pola pisane małymi literami mogą być kluczem: składnicą wartości obiektu lub po prostu nazwą pola z prefiksem lc_. Korzystam z drugiego, aby uprościć tworzenie zapytań (zapytania do obiektów głębokich mogą być czasami mylące).
Uwaga: chcesz zindeksować pola lc_, a nie główne pola, na których są oparte.
źródło
Załóżmy, że chcesz wyszukać „kolumnę” w „Tabeli” i chcesz wyszukiwać bez rozróżniania wielkości liter. Najlepszy i skuteczny sposób jest taki jak poniżej;
Powyższy kod po prostu dodaje wartość wyszukiwania jako RegEx i wyszukuje według niewrażliwych kryteriów ustawionych z opcją „i”.
Wszystkiego najlepszego.
źródło
Przy użyciu Mongoose to działało dla mnie:
źródło
.toLowerCase()
zbędne, jeśli określasz flagę bez rozróżniania wielkości literi
?Ramy agregacji zostały wprowadzone w mongodb 2.2. Możesz użyć operatora łańcuchowego „$ strcasecmp”, aby rozróżnić ciągi znaków bez rozróżniania wielkości liter. Jest to bardziej zalecane i łatwiejsze niż użycie wyrażenia regularnego.
Oto oficjalny dokument dotyczący operatora polecenia agregacji: https://docs.mongodb.com/manual/reference/operator/aggregation/strcasecmp/#exp._S_strcasecmp .
źródło
Możesz użyć indeksów bez rozróżniania wielkości liter :
Poniższy przykład tworzy kolekcję bez domyślnego sortowania, a następnie dodaje indeks do pola nazwy z sortowaniem bez rozróżniania wielkości liter. Międzynarodowe komponenty dla Unicode
Aby użyć indeksu, zapytania muszą określać to samo sortowanie.
lub możesz utworzyć kolekcję z domyślnym zestawieniem:
źródło
db.users.createIndex( { name: 1 }, {collation: { locale: 'tr', strength: 2 } } )
Aby wyszukać zmienną i uciec od niej:
Zmiana znaczenia chroni kwerendę przed atakami za pomocą „. *” Lub innego wyrażenia regularnego.
wyrażenie-łańcuchowe-wyrażenie-regularne
źródło
Użyj RegExp , w przypadku, gdy jakiekolwiek inne opcje nie działają dla Ciebie, RegExp jest dobrą opcją. Powoduje to, że ciąg nie rozróżnia wielkości liter.
użyj nazwy użytkownika w zapytaniach, a następnie gotowe.
Mam nadzieję, że to również zadziała dla ciebie. Wszystkiego najlepszego.
źródło
Stworzyłem prosty Func dla wyrażenia regularnego bez rozróżniania wielkości liter, którego używam w moim filtrze.
Następnie po prostu filtruj według pola w następujący sposób.
źródło
Użycie filtra działa dla mnie w C #.
Może nawet użyć indeksu, ponieważ uważam, że metody są wywoływane po powrocie, ale jeszcze tego nie przetestowałem.
Pozwala to również uniknąć problemu
ten mongodb uzna, że p.Title.ToLower () jest właściwością i nie będzie poprawnie mapowany.
źródło
Dla każdego, kto używa Golanga i chce mieć rozróżnianie wielkości liter w wyszukiwaniu pełnotekstowym za pomocą mongodb i biblioteki globalsign mgo godoc .
źródło
Jak widać w dokumentach mongo - ponieważ
$text
indeks wersji 3.2 domyślnie nie rozróżnia wielkości liter: https://docs.mongodb.com/manual/core/index-text/#text-index-case-insenssensUtwórz indeks tekstowy i użyj operatora $ text w zapytaniu .
źródło
username: 'bill'
dopasowanieBILL
lubBill
nie kwerendy wyszukiwania pełnotekstowego, która będzie również mecz wynikała słowa obill
, takie jakBills
,billed
itd.Zostały one przetestowane pod kątem wyszukiwania ciągów
źródło
Miałem do czynienia z podobnym problemem i właśnie to działało dla mnie:
źródło
$regex
i$options
. Co zrobiłeś Ctrl + F?$regex
jest nieefektywne i potencjalnie niebezpieczne, jak wyjaśniłem w mojej edycji tej drugiej odpowiedzi z 2016 r . Nie ma wstydu w usuwaniu odpowiedzi, jeśli nie służą już społeczności!