$ expr
内のすべて
は集計式であり、ドキュメントは「明示的にできないと言う」ことはできません。 、ただし、名前付き演算子の欠如
および $ where
代わりに:
db.getCollection('permits').find({
"$where": function() {
var description = this.inspections
.sort((a,b) => b.inspectionDate.valueOf() - a.inspectionDate.valueOf())
.shift().description;
return /^Found a .* at the property$/.test(description) ||
description === "Health Inspection";
}
})
$ expr
は引き続き使用できます
完全一致の集計式、または $ where
とりあえず。ただし、現時点では、MongoDBが理解できる正規表現は $regexのみです。
「クエリ」式
内 。
実際に「必要」した場合 $whereを使用できないようにする集計パイプライン式コード>
、現在有効な唯一のアプローチは、最初にアレイとは別にフィールドを「投影」し、次に $ match
通常のクエリ式を使用:
db.getCollection('permits').aggregate([
{ "$addFields": {
"lastDescription": {
"$arrayElemAt": [
"$inspections.description",
{ "$indexOfArray": [
"$inspections.inspectionDate",
{ "$max": "$inspections.inspectionDate" }
]}
]
}
}},
{ "$match": {
"lastDescription": {
"$in": [/^Found a .* at the property$/,/Health Inspection/]
}
}}
])
これは、最大の日付値を持つ配列内のアイテムを探しているように見えるという事実につながります。 JavaScript構文は、ここでの正しいアプローチが代わりにであることを明確にする必要があります $ sort
「更新」の配列。このようにして、配列の「最初の」項目を「最新」にすることができます。そして、これは通常のクエリで実行できることです。
順序を維持するには、 $ push
および $ sort
このように:
db.getCollection('permits').updateOne(
{ "_id": _idOfDocument },
{
"$push": {
"inspections": {
"$each": [{ /* Detail of inspection object */ }],
"$sort": { "inspectionDate": -1 }
}
}
}
)
実際、 $ each
>
updateMany()
既存のすべてのドキュメントを更新します:
db.getCollection('permits').updateMany(
{ },
{
"$push": {
"inspections": {
"$each": [],
"$sort": { "inspectionDate": -1 }
}
}
}
)
これらは実際に更新中に保存された日付を「変更」する場合にのみ必要であり、これらの更新は bullkWrite()
アレイの更新と「ソート」の「両方」を効果的に行うには:
db.getCollection('permits').bulkWrite([
{ "updateOne": {
"filter": { "_id": _idOfDocument, "inspections._id": indentifierForArrayElement },
"update": {
"$set": { "inspections.$.inspectionDate": new Date() }
}
}},
{ "updateOne": {
"filter": { "_id": _idOfDocument },
"update": {
"$push": { "inspections": { "$each": [], "$sort": { "inspectionDate": -1 } } }
}
}}
])
ただし、実際に日付を「変更」したことがない場合は、単に $ position
修飾子と「追加」の代わりに配列に「事前追加」し、 $ sort
:
db.getCollection('permits').updateOne(
{ "_id": _idOfDocument },
{
"$push": {
"inspections": {
"$each": [{ /* Detail of inspection object */ }],
"$position": 0
}
}
}
)
配列が永続的に並べ替えられるか、少なくとも「最新の」日付が実際には常に「最初の」エントリになるように作成されている場合は、通常のクエリ式を使用できます。
db.getCollection('permits').find({
"inspections.0.description": {
"$in": [/^Found a .* at the property$/,/Health Inspection/]
}
})
したがって、ここでの教訓は、実際には必要のないロジックに計算式を強制しようとしないことです。アレイのコンテンツを「保存済み」として注文して「最新の日付を最初の」にすることができないという説得力のある理由はありません。 " 、そして他の順序でアレイが必要だと思ったとしても、どちらの使用例がより重要であるかを検討する必要があります。
正規表現が文字列の先頭に固定されているか、クエリ式の少なくとも他の何かが完全に一致する限り、インデックスをある程度利用することもできます。
アレイを実際に並べ替えることができないと思われる場合は、 $ where
JIRAの問題が解決するまでは、クエリが唯一の選択肢です。これは、現在目標としている4.1リリースで実際に行われることを願っていますが、せいぜい6か月から1年である可能性が高いです。