$push、$each、$slice を使用して、配列内のサブドキュメントを並べ替えます。 |
|
1.$push 演算子
1.1 構文と関数の説明
$push は主に配列に要素を追加するために使用されます。
構文:
{ $push: { <field1>: <value1>, ... } }
ログイン後にコピー
デフォルトでは、配列の末尾に 1 つの要素が追加されます。
1.2 操作ケース
学生のスコア、studentscore のコレクションがあり、そのドキュメント形式が次のとおりであるとします。
{ "_id" : 1, "name" : "xiaoming", "score" : [ { "math" : 99, "english" : 89 } ] }
{ "_id" : 2, "name" : "xiaohong", "score" : [ { "math" : 98, "english" : 96 } ] }
ログイン後にコピー
ここでの要件は、_id 1 でドキュメント レコードを更新し、スコア配列のフィールドに物理等級を追加し、コードを
db.studentscore.update({_id:1},{$push: {score:{"physics":100}}})
ログイン後にコピー
## に変更することです。 #修正後の結果クエリは次のようになります: { "_id" : 1, "name" : "xiaoming", "score" : [ { "math" : 99, "english" : 89 }, { "physics" : 100 } ] }
{ "_id" : 2, "name" : "xiaohong", "score" : [ { "math" : 98, "english" : 96 } ] }
ログイン後にコピー
1.3 $each 修飾子と組み合わせて、バッチ挿入If 複数の値配列に一度に追加されます。配列修飾子 $each と組み合わせて使用できます。 <span class="pre"></span>
たとえば、Xiaohong (_id =2) の物理スコア、化学スコア、生物学スコアをドキュメントに追加します。実行されたステートメントは次のとおりです: <span class="pre"></span>
db.studentscore.update({ _id: 2 },
{
$push: {
score: {
$each: [{ "physics": 100 }, { "chemistry": 90 }, { "biology": 99 }]
}
}
}
)
ログイン後にコピー
クエリの結果は次のとおりです: { "_id" : 1, "name" : "xiaoming", "score" : [ { "math" : 99, "english" : 89 }, { "physics" : 100 } ] }
{ "_id" : 2, "name" : "xiaohong", "score" : [ { "math" : 98, "english" : 96 }, { "physics" : 100 }, { "chemistry" : 90 }, { "biology" : 99 } ] }
ログイン後にコピー
1.4 配列修飾子 $sort と $slice の使用#$each 配列操作修飾子については前に説明しました。残りの 2 つの修飾子を説明するために別の例を示します。 $sort と $slice)
たとえば、次のドキュメントがあります:
{
"_id" : 5,
"quizzes" : [
{ "wk": 1, "score" : 10 },
{ "wk": 2, "score" : 8 },
{ "wk": 3, "score" : 5 },
{ "wk": 4, "score" : 6 }
]
}
ログイン後にコピー
ここで、要件があります。ドキュメントのクイズ配列フィールドに 3 つのレコードを追加し、スコア順に並べ替えて、配列内の最初の 3 つの要素を選択します。
db.students.update(
{ _id: 5 },
{
$push: {
quizzes: {
$each: [ { wk: 5, score: 8 }, { wk: 6, score: 7 }, { wk: 7, score: 6 } ],
$sort: { score: -1 },
$slice: 3
}
}
}
)
ログイン後にコピー
更新された結果は次のように表示されます:
{
"_id" : 5,
"quizzes" : [
{ "wk" : 1, "score" : 10 },
{ "wk" : 2, "score" : 8 },
{ "wk" : 5, "score" : 8 } ]}
ログイン後にコピー
$slice 操作修飾子頻繁に更新される配列の管理を容易にするために、MongoDB 2.4 に追加されました。この演算子は、配列に値を追加するが、配列を大きくしすぎたくない場合に便利です。これは $push 演算子および $each 演算子と一緒に使用する必要があり、配列のサイズを短縮したり、古い値を削除したりするために使用できるようになります。
$slice 操作修飾子と同様に、MongoDB 2.4 には、配列の更新を支援する新しい $sort 操作修飾子が追加されています。 $push と $slice を使用する場合、場合によっては並べ替えてから削除する必要があります。
2. $pop 演算子
2.1 構文と関数の説明
$pop 演算子は、配列から最初または最良の要素を削除できます。
{ $pop: { <field>: <-1 | 1>, ... } }
ログイン後にコピー
パラメータは -1 で、配列の最初の要素が削除されることを意味します。パラメータが 1 の場合、配列の最後の要素が削除されることを意味します。配列が削除されます。
2.2 運用ケース
たとえば、学生のコレクションには次の文書があります:
{ _id: 1, scores: [ 8, 9, 10 ] }
ログイン後にコピー
私たちが必要としているのは、最初の要素 (スコア 8) が削除され、SQL ステートメントは次のようになります。
db.students.update( { _id: 1 }, { $pop: { scores: -1 } } )
ログイン後にコピー
更新後のドキュメントは次のようになります。続いて
#
{ _id: 1, scores: [ 9, 10 ] }
ログイン後にコピー
デモを続けます。既存のベースに基づいて配列の最後の要素 (スコアは 10) をさらに削除する必要がある場合、更新された SQL は次のようになります。 db.students.update( { _id: 1 }, { $pop: { scores: 1 } } )
ログイン後にコピー
クエリ結果は次のとおりです:{ _id: 1, scores: [ 9 ] }
ログイン後にコピー
3。 $pull 演算子 <span class="pre"></span>
3.1 構文と関数の説明
$pull は $pop の複雑な形式です。 $pull を使用すると、削除する要素を値で正確に指定できます。
構文形式{ $pull: { <field1>: <value|condition>, <field2>: <value|condition>, ... } }
ログイン後にコピー
3.2 操作ケース3.2.1 指定された値#に等しいを削除します。 array 要素
テスト ドキュメントは次のとおりです:
{
_id: 1,
fruits: [ "apples", "pears", "oranges", "grapes", "bananas" ],
vegetables: [ "carrots", "celery", "squash", "carrots" ]}
{
_id: 2,
fruits: [ "plums", "kiwis", "oranges", "bananas", "apples" ],
vegetables: [ "broccoli", "zucchini", "carrots", "onions" ]}
ログイン後にコピー
操作要件は
" を追加することです配列フィールドのリンゴ、果物「
および <span class="pre">「オレンジ」が削除され、野菜配列フィールドの「ニンジン」も削除されます。更新ステートメントは次のとおりです: </span>
<span class="pre"></span>db.stores.update(
{ },
{ $pull: { fruits: { $in: [ "apples", "oranges" ] }, vegetables: "carrots" } },
{ multi: true }
)
ログイン後にコピー
更新された結果は次のとおりです:
{
"_id" : 1,
"fruits" : [ "pears", "grapes", "bananas" ],
"vegetables" : [ "celery", "squash" ]}
{
"_id" : 2,
"fruits" : [ "plums", "kiwis", "bananas" ],
"vegetables" : [ "broccoli", "zucchini", "onions" ]}
ログイン後にコピー
現時点では、コレクション ドキュメントの果物の配列フィールドには
リンゴや
<span class="pre">オレンジはなく、野菜の配列フィールドにはニンジンはありません。 </span>
<span class="pre">3.2.2 </span>指定された条件を満たす要素を配列から削除します
プロファイルのコレクションがある場合、そのドキュメント形式は次のとおりです。 :
{ _id: 1, votes: [ 3, 5, 6, 7, 7, 8 ] }
ログイン後にコピー
投票数が 6 以上の要素を削除したいと考えています。ステートメントは次のとおりです:
db.profiles.update( { _id: 1 }, { $pull: { votes: { $gte: 6 } } } )
ログイン後にコピー
更新された結果は次のとおりです:
{ _id: 1, votes: [ 3, 5 ] }
ログイン後にコピー
3.2.3 移除数组中内嵌子文档(即此时数组元素是子文档,每一个{}中的内容是一个数组元素)
假设我们有一个关于 调查的集合 survey,其数据如下:
{
_id: 1,
results: [
{ item: "A", score: 5 },
{ item: "B", score: 8, comment: "Strongly agree" } ]}
{
_id: 2,
results: [
{ item: "C", score: 8, comment: "Strongly agree" },
{ item: "B", score: 4 } ]}
ログイン後にコピー
需求是将 <span class="pre">score 为</span>
<span class="pre">8</span>
并且 <span class="pre">item</span>
为 <span class="pre">"B"的元素移除</span>
db.survey.update(
{ },
{ $pull: { results: { score: 8 , item: "B" } } },
{ multi: true }
)
ログイン後にコピー
更新后的文档如下:
{
"_id" : 1,
"results" : [ { "item" : "A", "score" : 5 } ]}
{
"_id" : 2,
"results" : [
{ "item" : "C", "score" : 8, "comment" : "Strongly agree" },
{ "item" : "B", "score" : 4 } ]}
ログイン後にコピー
3.2.4 如果数组类型的元素还内嵌一个数组(数组包数组),就要特别小心了。
此时就要用到 <span class="pre">$elemMatch操作符。</span>
例如 文档格式如下:
{
_id: 1,
results: [
{ item: "A", score: 5, answers: [ { q: 1, a: 4 }, { q: 2, a: 6 } ] },
{ item: "B", score: 8, answers: [ { q: 1, a: 8 }, { q: 2, a: 9 } ] }
]
}
{
_id: 2,
results: [
{ item: "C", score: 8, answers: [ { q: 1, a: 8 }, { q: 2, a: 7 } ] },
{ item: "B", score: 4, answers: [ { q: 1, a: 0 }, { q: 2, a: 8 } ] }
]
}
ログイン後にコピー
需要将 results数组字段 移除,移除的条件是 results数组字段中的answers字段,符合 <span class="pre">q</span>
为 <span class="pre">2</span>
and <span class="pre">a</span>
大于等于 <span class="pre">8。</span>
db.survey.update(
{ },
{ $pull: { results: { answers: { $elemMatch: { q: 2, a: { $gte: 8 } } } } } },
{ multi: true }
)
ログイン後にコピー
更新后的数据如下:
{
"_id" : 1,
"results" : [
{ "item" : "A", "score" : 5, "answers" : [ { "q" : 1, "a" : 4 }, { "q" : 2, "a" : 6 } ] }
]
}
{
"_id" : 2,
"results" : [
{ "item" : "C", "score" : 8, "answers" : [ { "q" : 1, "a" : 8 }, { "q" : 2, "a" : 7 } ] }
]
}
ログイン後にコピー
4.$addToSet
4.1 语法及功能描述
使用$addToSet也会往数组后面添加值,但是它比较特殊:它只会添加数组里不存在的值。
{ $addToSet: { <field1>: <value1>, ... } }
ログイン後にコピー
4.2 操作案例
假如有一个集合 <span class="pre">inventory</span>
格式如下
{ _id: 1, item: "polarizing_filter", tags: [ "electronics", "camera" ] }
ログイン後にコピー
我们希望向向字段 tags 数组 ,添加一个元素accessories,则更新语句如下:
db.inventory.update(
{ _id: 1 },
{ $addToSet: { tags: "accessories" } }
)
ログイン後にコピー
更新后的结果为
{ "_id" : 1, "item" : "polarizing_filter", "tags" : [ "electronics", "camera", "accessories" ] }
ログイン後にコピー
如果想批量的增加如果元素,我们可以结合 <span class="pre">$each 操作符一起使用。</span>
例如以下文档
{ _id: 2, item: "cable", tags: [ "electronics", "supplies" ] }
ログイン後にコピー
我们想在字段 tags 数组,添加元素 "camera", "electronics", "accessories",则更新语句如下:
db.inventory.update(
{ _id: 2 },
{ $addToSet: { tags: { $each: [ "camera", "electronics", "accessories" ] } } }
)
ログイン後にコピー
更新后的结果如下:
{
_id: 2,
item: "cable",
tags: [ "electronics", "supplies", "camera", "accessories" ]}
ログイン後にコピー
4.3 注意点
需要注意是,如果添加的元素是数组格式,则会将新添加的元素保留为数组(将会出现数组嵌套数组)
例如
{ _id: 1, letters: ["a", "b"] }
ログイン後にコピー
执行的语句如下:
db.test.update(
{ _id: 1 },
{ $addToSet: {letters: [ "c", "d" ] } }
)
ログイン後にコピー
查询结构显示为
{ _id: 1, letters: [ "a", "b", [ "c", "d" ] ] }
ログイン後にコピー