Obrigado pela amostra de dados. Minha resposta vai ser uma matéria-prima de MQL solução, não um mangusto solução, de modo algum a tradução será necessário.
Eu era capaz de inserir dois documentos, com base em seus comentários no seu post. Eu tive que mudar o ObjectId de um dos documentos de exemplo, porque o seu amostras apresentaram o mesmo valor de chave primária e estava gerando uma chave duplicada exceção.
Inserir Dados De Exemplo
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"
})
Se eu quero encontrar registros ter mais de 0 itens na matriz traces
Eu posso emitir os seguintes:
Encontrar mais do que zero traços
db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 0 ] } })
Isso retorna o seguinte:
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'
}
]
Encontrará mais de 1 de rastreamento
Se, em vez disso, eu quero encontrar mais do que um traço eu simplesmente alterar a consulta de um pouco:
db.CallerTraces.find({ $expr: { $gt: [ { $size: "$traces" }, 1 ] } })
... e esta retorna com os seguintes resultados:
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'
}
]
Conclusão
Ao tentar avaliar o comprimento da matriz dentro do processador de consultas devemos optar por usar o $eval
opção de como a sintaxe para MQL não considerar seu caso de uso. O $eval
é um pouco de um catch-all opção para as coisas que não se encaixam muito bem no MQL quadro.
ATUALIZAÇÃO #1
OP introduziu requisitos adicionais. Em vez de olhar para a contagem da matriz, deve-se considerar a contagem da matriz dentro da matriz (aninhados interior da matriz). Desde o encontrar (em) o método com o $expr não é possível avaliar matrizes aninhadas devemos, em vez disso, use a agregação de quadro e descontrair o exterior da matriz. Este exemplo armazena a forma original em um novo campo chamado original
em seguida, substitui a raiz depois de toda a avaliação é completa. Desde relaxamento pode resultar em duplicatas no pipeline nós finalize com um $grupo para suprimir duplicatas.
Solução
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" }
}
}
])