Dziękuję za próbkę danych. Moja odpowiedź będzie surowo rozwiązaniem MQL, a nie rozwiązaniem mangusta, więc trzeba niektóre tłumaczenia.
Udało mi się wstawić dwa dokumentu, na podstawie swoich komentarzach w poście. Musiałem zmienić identyfikator obiektu jednego z dwóch wzorów dokumentów, bo swoje próbki miały taką samą wartość klucza podstawowego i tworzyli wyjątkiem duplikatu klucza.
Włóż Przykłady Danych
db.CallerTraces.insert(
{
"_id": ObjectId("6175e7ecc62cff004462d4a6"),
"traces": [
[
ObjectId("6175e7ecc62cff004462d4a4")
]
],
"caller_address": "0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990"
})
db.CallerTraces.insert(
{
"_id": ObjectId("6175e7ecc62cff004462d4a7"),
"traces": [
[
ObjectId("6175e7ecc62cff004462d4a4"),
ObjectId("6175e7ecc62cff004462d4a4")
],
[
ObjectId("6175e7ecc62cff004462d4a4")
]
],
"caller_address": "0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990"
})
Jeśli chcę znaleźć rekordy zawierające ponad 0 elementów w tablicy traces
Mogę wydać następujący:
Znajdź więcej zero śladów
db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 0 ] } })
To zwraca następujący:
Enterprise replSet [primary] barrydb> db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 0 ] } })
[
{
_id: ObjectId("6175e7ecc62cff004462d4a6"),
traces: [ [ ObjectId("6175e7ecc62cff004462d4a4") ] ],
caller_address: '0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990'
},
{
_id: ObjectId("6175e7ecc62cff004462d4a7"),
traces: [
[
ObjectId("6175e7ecc62cff004462d4a4"),
ObjectId("6175e7ecc62cff004462d4a4")
],
[ ObjectId("6175e7ecc62cff004462d4a4") ]
],
caller_address: '0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990'
}
]
Znajdź ponad 1 śladu
Jeśli zamiast tego chcę znaleźć więcej niż jedną śledzenia, ja tylko lekko zmienić zapytanie:
db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 1 ] } })
... i to zwraca następujące wyniki:
Enterprise replSet [primary] barrydb> db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 1 ] } })
[
{
_id: ObjectId("6175e7ecc62cff004462d4a7"),
traces: [
[
ObjectId("6175e7ecc62cff004462d4a4"),
ObjectId("6175e7ecc62cff004462d4a4")
],
[ ObjectId("6175e7ecc62cff004462d4a4") ]
],
caller_address: '0x4e204793bc4b8acee32edaf1fbba1f3ea45f7990'
}
]
Wniosek
Przy próbie oceny długości tablicy w procesor zapytań musimy zdecydować się na stosowanie $eval
opcja jako składni dla MQL nie bierze pod uwagę możliwość użycia. To $eval
jest to swego rodzaju uniwersalnym rozwiązaniem dla rzeczy, które źle wpisują się w ramy MQL.
AKTUALIZACJA nr 1
OP wprowadziła dodatkowe wymagania. Zamiast patrzeć na ilość tablic, musimy wziąć pod uwagę ilość tablic wewnątrz tablicy (załączony wewnętrzny tablica). Ponieważ metoda find() z $expr nie może oceniać zagnieżdżone tablice, musimy zamiast tego użyj struktury agregacji i wdrożyć zewnętrzny tablicy. W tym przykładzie oryginalna forma jest zachowana w nowym polu o nazwie original
następnie zastępuje korzeń po zakończeniu całej oceny. Ponieważ rozwijanie i przenoszenie warstwy materiału może prowadzić do dwóch egzemplarzach w rurociągu, kończymy pracę z grupą $, aby stłumić duplikaty.
Rozwiązanie
db.CallerTraces.aggregate([
{
$addFields: {
"original._id": "$_id",
"original.traces": "$traces",
"original.caller_address": "$caller_address"
}
},
{
$unwind: "$traces"
},
{
$match: { $expr: { $gt: [ { $size: "$traces" }, 1 ] } }
},
{
$replaceRoot: { newRoot: "$original" }
},
{
$group:
{
_id: "$_id",
traces: { "$first": "$traces" },
caller_address: { "$first": "$caller_address" }
}
}
])