var thename = 'Andrew';
db.collection.find({'name':thename});
Jak zapytać o wielkość liter? Chcę znaleźć wynik, nawet jeśli „andrew”;
var thename = 'Andrew';
db.collection.find({'name':thename});
Jak zapytać o wielkość liter? Chcę znaleźć wynik, nawet jeśli „andrew”;
Odpowiedzi:
Rozwiązanie Chrisa Fulstowa zadziała (+1), jednak może nie być wydajne, zwłaszcza jeśli twoja kolekcja jest bardzo duża. Niezakorzenione wyrażenia regularne (te, które nie rozpoczynają się od ^
, które zakotwiczają wyrażenie regularne na początku ciągu) oraz te, które używają i
flagi dla niewrażliwości na wielkość liter, nie będą używać indeksów, nawet jeśli istnieją.
Alternatywną opcją, którą możesz rozważyć, jest denormalizacja danych w celu zapisania wersji name
pola z małymi literami , na przykład jako name_lower
. Następnie możesz efektywnie zapytać (zwłaszcza jeśli jest indeksowany) o dokładne dopasowania bez rozróżniania wielkości liter, takie jak:
db.collection.find({"name_lower": thename.toLowerCase()})
Lub z dopasowaniem prefiksu (zakorzenione wyrażenie regularne) jako:
db.collection.find( {"name_lower":
{ $regex: new RegExp("^" + thename.toLowerCase(), "i") } }
);
Oba te zapytania będą używać indeksu name_lower
.
new RegExp('^'+ username + '$', "i")
aby być dokładnym dopasowaniem.
".*"
.
W tym przypadku musiałbyś użyć wyrażenia regularnego bez rozróżniania wielkości liter , np
db.collection.find( { "name" : { $regex : /Andrew/i } } );
Aby użyć wzorca wyrażenia regularnego ze thename
zmiennej, utwórz nowy obiekt RegExp :
var thename = "Andrew";
db.collection.find( { "name" : { $regex : new RegExp(thename, "i") } } );
Aktualizacja: aby uzyskać dokładne dopasowanie, użyj wyrażenia regularnego "name": /^Andrew$/i
. Dzięki Yannick L.
name
, a nie tylko z równaniem.
{ "name": /^Andrew$/i }
Rozwiązałem to w ten sposób.
var thename = 'Andrew';
db.collection.find({'name': {'$regex': thename,$options:'i'}});
Jeśli chcesz zapytać o „dopasowanie ścisłe bez rozróżniania wielkości liter”, możesz to zrobić w ten sposób.
var thename = '^Andrew$';
db.collection.find({'name': {'$regex': thename,$options:'i'}});
MongoDB 3.4 zawiera teraz możliwość tworzenia prawdziwego indeksu bez rozróżniania wielkości liter, co znacznie zwiększy szybkość wyszukiwania bez rozróżniania wielkości liter w dużych zestawach danych. Dokonuje się tego przez określenie zestawienia o sile 2.
Prawdopodobnie najłatwiejszym sposobem jest ustawienie sortowania w bazie danych. Następnie wszystkie zapytania dziedziczą to sortowanie i będą z niego korzystać:
db.createCollection("cities", { collation: { locale: 'en_US', strength: 2 } } )
db.names.createIndex( { city: 1 } ) // inherits the default collation
Możesz to również zrobić w ten sposób:
db.myCollection.createIndex({city: 1}, {collation: {locale: "en", strength: 2}});
I użyj tego w ten sposób:
db.myCollection.find({city: "new york"}).collation({locale: "en", strength: 2});
Spowoduje to zwrócenie miast o nazwach „Nowy Jork”, „Nowy Jork”, „Nowy Jork” itp.
Więcej informacji: https://jira.mongodb.org/browse/SERVER-90
W przypadku Mongoose (i Node) to zadziałało:
User.find({ email: /^name@company.com$/i })
User.find({ email: new RegExp(
`^ $ {emailVariable} $`, 'i')})
W MongoDB to zadziałało:
db.users.find({ email: { $regex: /^name@company.com$/i }})
W obu wierszach wielkość liter nie jest rozróżniana. E-mail w bazie danych mógłby byćNaMe@CompanY.Com
a obie linie nadal będą znajdować obiekt w bazie danych.
Podobnie moglibyśmy użyć /^NaMe@CompanY.Com$/i
i nadal znajdowałby email: name@company.com
w bazie danych.
Aby znaleźć ciąg niewrażliwy na wielkość liter, użyj tego,
var thename = "Andrew";
db.collection.find({"name":/^thename$/i})
Właśnie rozwiązałem ten problem kilka godzin temu.
var thename = 'Andrew'
db.collection.find({ $text: { $search: thename } });
Możesz nawet rozszerzyć ten zakres, wybierając potrzebne pola z obiektu użytkownika Andrew, robiąc to w ten sposób:
db.collection.find({ $text: { $search: thename } }).select('age height weight');
Źródła: https://docs.mongodb.org/manual/reference/operator/query/text/#text
... z mongoose w NodeJS, które zapytanie:
const countryName = req.params.country;
{ 'country': new RegExp(`^${countryName}$`, 'i') };
lub
const countryName = req.params.country;
{ 'country': { $regex: new RegExp(`^${countryName}$`), $options: 'i' } };
// ^australia$
lub
const countryName = req.params.country;
{ 'country': { $regex: new RegExp(`^${countryName}$`, 'i') } };
// ^turkey$
Przykład pełnego kodu w JavaScript, NodeJS z Mongoose ORM w MongoDB
// get all customers that given country name
app.get('/customers/country/:countryName', (req, res) => {
//res.send(`Got a GET request at /customer/country/${req.params.countryName}`);
const countryName = req.params.countryName;
// using Regular Expression (case intensitive and equal): ^australia$
// const query = { 'country': new RegExp(`^${countryName}$`, 'i') };
// const query = { 'country': { $regex: new RegExp(`^${countryName}$`, 'i') } };
const query = { 'country': { $regex: new RegExp(`^${countryName}$`), $options: 'i' } };
Customer.find(query).sort({ name: 'asc' })
.then(customers => {
res.json(customers);
})
.catch(error => {
// error..
res.send(error.message);
});
});
Następujące zapytanie znajdzie dokumenty z wymaganym ciągiem bez uwzględnienia, a także z wystąpieniem globalnym
db.collection.find({name:{
$regex: new RegExp(thename, "ig")
}
},function(err, doc) {
//Your code here...
});
Aby znaleźć ciąg literałów bez rozróżniania wielkości liter:
db.collection.find({
name: {
$regex: new RegExp('^' + name.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '$', 'i')
}
});
db.collection.find({
name_lower: name.toLowerCase()
});
Wyrażenia regularne są wolniejsze niż dopasowywanie literałów. Jednak dodatkowe pole z małą literą zwiększy złożoność kodu. W razie wątpliwości użyj wyrażeń regularnych. Sugerowałbym użycie pola z wyraźnie małymi literami tylko wtedy, gdy może ono zastąpić twoje pole, to znaczy nie przejmujesz się wielkością liter.
Pamiętaj, że przed wprowadzeniem wyrażenia regularnego będziesz musiał uciec przed nazwą. Jeśli chcesz .replace(/%/g, '.*')
używać symboli wieloznacznych wprowadzanych przez użytkownika, preferuj dołączanie po znaku ucieczki, aby można było dopasować „a%”, aby znaleźć wszystkie nazwy zaczynające się od „a”.
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 uwzględniania wielkości liter. Komponenty międzynarodowe dla Unicode
/*
* strength: CollationStrength.Secondary
* Secondary level of comparison. Collation performs comparisons up to secondary * differences, such as diacritics. That is, collation performs comparisons of
* base characters (primary differences) and diacritics (secondary differences). * Differences between base characters takes precedence over secondary
* differences.
*/
db.users.createIndex( { name: 1 }, collation: { locale: 'tr', strength: 2 } } )
Aby użyć indeksu, kwerendy muszą określać to samo sortowanie.
db.users.insert( [ { name: "Oğuz" },
{ name: "oğuz" },
{ name: "OĞUZ" } ] )
// does not use index, finds one result
db.users.find( { name: "oğuz" } )
// uses the index, finds three results
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 2 } )
// does not use the index, finds three results (different strength)
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 1 } )
lub możesz utworzyć kolekcję z domyślnym sortowaniem:
db.createCollection("users", { collation: { locale: 'tr', strength: 2 } } )
db.users.createIndex( { name : 1 } ) // inherits the default collation
Prostym sposobem byłoby użycie $ toLower, jak poniżej.
db.users.aggregate([
{
$project: {
name: { $toLower: "$name" }
}
},
{
$match: {
name: the_name_to_search
}
}
])