Mam kolekcję MongoDB z dokumentami w następującym formacie:
{
"_id" : ObjectId("4e8ae86d08101908e1000001"),
"name" : ["Name"],
"zipcode" : ["2223"]
}
{
"_id" : ObjectId("4e8ae86d08101908e1000002"),
"name" : ["Another ", "Name"],
"zipcode" : ["2224"]
}
Obecnie mogę uzyskać dokumenty pasujące do określonego rozmiaru tablicy:
db.accommodations.find({ name : { $size : 2 }})
To poprawnie zwraca dokumenty z 2 elementami w name
tablicy. Nie mogę jednak wykonać $gt
polecenia, aby zwrócić wszystkie dokumenty, w których name
pole ma rozmiar tablicy większy niż 2:
db.accommodations.find({ name : { $size: { $gt : 1 } }})
Jak mogę wybrać wszystkie dokumenty z name
tablicą o rozmiarze większym niż jeden (najlepiej bez konieczności modyfikowania bieżącej struktury danych)?
mongodb
mongodb-query
Emson
źródło
źródło
Odpowiedzi:
Aktualizacja:
Dla wersji MongoDB 2.2+ bardziej efektywny sposób to zrobić opisane przez @JohnnyHK w innej odpowiedzi .
1. Za pomocą $ gdzie
Ale...
2. Utwórz dodatkowe pole
NamesArrayLength
, zaktualizuj je o długość tablicy nazw, a następnie użyj w zapytaniach:Będzie to lepsze rozwiązanie i będzie działało znacznie szybciej (możesz na nim utworzyć indeks).
źródło
$where
, jest bardzo elastyczny.Istnieje bardziej wydajny sposób na wykonanie tego w MongoDB 2.2+, ponieważ można używać indeksów tablic numerycznych w kluczach obiektów zapytań.
Możesz wesprzeć to zapytanie za pomocą indeksu, który używa częściowego wyrażenia filtrującego (wymaga wersji 3.2+):
źródło
{'Name Field.1': {$exists: true}}
.name
zawiera co najmniej 1 element, ale OP szukał więcej niż 1.Uważam, że jest to najszybsze zapytanie, które odpowiada na twoje pytanie, ponieważ nie używa interpretowanej
$where
klauzuli:Oznacza to „wszystkie dokumenty oprócz tych bez nazwy (nieistniejącej lub pustej tablicy) lub z tylko jedną nazwą”.
Test:
źródło
{'name.1': {$exists: true}}
'name.1': {$exists: true}}
, a także dlatego, że jest ona zakodowana na „1” i nie skaluje się do arbitralnej lub parametrycznej minimalnej długości tablicy.Możesz także użyć agregacji:
// dodajesz „rozmiar_nazwy” do dokumentu transportowego i używasz go do filtrowania rozmiaru nazwy
źródło
Spróbuj zrobić coś takiego:
1 jest liczbą, jeśli chcesz pobrać rekord większy niż 50, to zrób ArrayName.50 Dzięki.
źródło
Żadne z powyższych nie działało dla mnie. Ten zrobił, więc dzielę się tym:
źródło
Możesz użyć $ expr (operator wersji mongo 3.6), aby użyć funkcji agregujących w regularnym zapytaniu.
Porównaj
query operators
vsaggregation comparison operators
.źródło
$name
tablicy, która jest dokument podrzędny, na przykład w „osoba” rekordupassport.stamps
? Próbowałem różnych kombinacji cytatów, ale dostaję"The argument to $size must be an array, but was of type: string/missing"
.db.col.find({$expr:{$gt:[{$size:{$ifNull:["$passport.stamps", []]}}, 1]}})
źródło
MongoDB 3.6 zawiera $ expr https://docs.mongodb.com/manual/reference/operator/query/expr/
Możesz użyć $ expr, aby ocenić wyrażenie w dopasowaniu $ lub znaleźć.
lub znajdź
źródło
Znalazłem to rozwiązanie, aby znaleźć przedmioty o polu tablicy większym niż pewna długość
W agregacji pierwszego dopasowania $ użyto argumentu, który jest prawdziwy dla wszystkich dokumentów. Jeśli puste, dostanę
źródło
Znam jego stare pytanie, ale próbuję tego z $ gte i $ size w znalezieniu. Myślę, że znalezienie () jest szybsze.
źródło
Chociaż powyższe odpowiedzi działają poprawnie, to, co pierwotnie próbowałeś zrobić, było poprawne, ale masz tylko składnię wstecz (przełącz „$ size” i „$ gt”) ..
Poprawny:
Błędny:
źródło