MongoDBのオブジェクトへのデータ型の更新 -- database フィールド と mongodb フィールド と types フィールド 関連 問題

Updating data type to an Object in mongoDB












0
vote

問題

日本語

私は、2つの文字列を含むオブジェクトの配列に、文字列の配列からMongoDBで私のコレクションのフィールドの1つを変更しました。新しい文書が問題なく挿入されますが、GETメソッドが取得され、すべての文書を照会する場合は、このエラーが発生します。

学生の復号化に失敗しました。 「フォトライドデレッシ」エラーを解読しました with:ReadStartDocumentは、CurrentBontypeがあるときにのみ呼び出すことができます CurrentBSontypeが文字列のときではないドキュメント。

PhotoAddressesは、学生で変更されたフィールドです。

私はすべてのレコードを更新する方法がすべてデータ型を失うことなく、すべてのレコードを更新する方法がありました。

PhotoAdressesの古いバージョン:

<事前> <コード> "photoAddresses" : ["something","something else"]

これはこのような新しいバージョンに更新されるべきです:

<事前> <コード> "photoAddresses" : [{photoAddresses:"something"},{photoAddresses:"something else"}]
英語

I have changed one of the fields of my collection in mongoDB from an array of strings to an array of object containing 2 strings. New documents get inserted without any problem, but when a get method is called to get , querying all the documents I get this error:

Failed to decode 'Students'. Decoding 'photoAddresses' errored with: readStartDocument can only be called when CurrentBSONType is DOCUMENT, not when CurrentBSONType is STRING.

photoAddresses is the field that was changed in Students.

I was wondering is there any way to update all the records so they all have the same data type, without losing any data.

The old version of photoAdresses:

"photoAddresses" : ["something","something else"] 

This should be updated to the new version like this:

"photoAddresses" : [{photoAddresses:"something"},{photoAddresses:"something else"}] 
</div
        
         
         

回答リスト

1
 
vote
vote
ベストアンサー
 

次の集約クエリは、配列が文字列要素を持つ場合にのみ、ストリングアレイをオブジェクト配列に更新します。集約演算子 $ map はマッピングするために使用されます。 string アレイ要素。 2つのクエリを使用できます。

<事前> <コード> db.test.aggregate( [ { $match: { $expr: { $and: [ { $isArray: "$photo" }, { $gt: [ { $size: "$photo" }, 0 ] } ] }, "photo.0": { $type: "string" } } }, { $project: { photo: { $map: { input: "$photo", as: "ph", in: { addr: "$$ph" } } } } }, ] ).forEach( doc => db.test.updateOne( { _id: doc._id }, { $set: { photo: doc.photo } } ) )


> 次のクエリは、MongoDBバージョン4.2以降でのみ機能します。 (注)更新操作は、 update の代わりに集約です。 updatemany

。 <事前> <コード> db.test.updateMany( { $expr: { $and: [ { $isArray: "$photo" }, { $gt: [ { $size: "$photo" }, 0 ] } ] }, "photo.0": { $type: "string" } }, [ { $set: { photo: { $map: { input: "$photo", as: "ph", in: { addr: "$$ph" } } } } } ] )


>


[ edit ]:次のクエリはバージョン mongodb 3.4 で動作します。 <事前> <コード> db.test.aggregate( [ { $addFields: { matches: { $cond: { if: { $and: [ { $isArray: "$photoAddresses" }, { $gt: [ { $size: "$photoAddresses" }, 0 ] }, { $eq: [ { $type: { $arrayElemAt: [ "$photoAddresses", 0 ] } }, "string" ] } ] }, then: true, else: false } } } }, { $match: { matches: true } }, { $project: { photoAddresses: { $map: { input: "$photoAddresses", as: "ph", in: { photoAddresses: "$$ph" } } } } }, ] ).forEach( doc => db.test.updateOne( { _id: doc._id }, { $set: { photoAddresses: doc.photoAddresses } } ) )
 

The following aggregation queries update the string array to object array, only if the array has string elements. The aggregation operator $map is used to map the string array elements to objects. You can use any of the two queries.

db.test.aggregate( [   {        $match: {            $expr: { $and: [ { $isArray: "$photo" },                             { $gt: [ { $size: "$photo" }, 0 ] }                          ]            },            "photo.0": { $type: "string" }       }    },   {       $project: {           photo: {                $map: {                    input: "$photo",                        as: "ph",                        in: { addr: "$$ph" }                 }            }       }    }, ] ).forEach( doc => db.test.updateOne( { _id: doc._id }, { $set: { photo: doc.photo } } ) ) 


The following query works with MongoDB version 4.2+ only. Note the update operation is an aggregation instead of an update. See updateMany.

db.test.updateMany(   {            $expr: { $and: [ { $isArray: "$photo" },                             { $gt: [ { $size: "$photo" }, 0 ] }                          ]            },            "photo.0": { $type: "string" }   },   [     {       $set: {           photo: {                $map: {                    input: "$photo",                        as: "ph",                        in: { addr: "$$ph" }                 }            }       }      }   ] ) 



[EDIT ADD]: The following query works with version MongoDB 3.4:
db.test.aggregate( [   {        $addFields: {            matches: {               $cond: {                   if: { $and: [                            { $isArray: "$photoAddresses" },                            { $gt: [ { $size: "$photoAddresses" }, 0 ] },                           { $eq: [ { $type: { $arrayElemAt: [ "$photoAddresses", 0 ] } }, "string" ] }                        ] },                   then: true,                   else: false               }           }       }   },   {       $match: { matches: true }   },   {       $project: {           photoAddresses: {                $map:  {                    input: "$photoAddresses",                        as: "ph",                        in: { photoAddresses: "$$ph" }                 }            }       }    }, ] ).forEach( doc => db.test.updateOne( { _id: doc._id }, { $set: { photoAddresses: doc.photoAddresses } } ) ) 
</div
 
 
     
     

関連する質問

10  画像を保存するために使用するのはどのような変数型ですか?  ( What variable type should i use to save an image ) 
私はイメージをSQLデータベースに保存するつもりです(そこで使用するタイプがわかりません)、そして私は学生の肖像撮影のイメージのためにDBを照会するつもりです。 この画像を保存するためにどのような変数型を使用すべきか? <事前> <コード> using Sys...

84  C / C ++で長い長い  ( Long long in c c ) 
GNUのC ++コンパイラでこのコードを試していて、その動作を理解できません: <事前> <コード> #include <stdio.h>; int main() { int num1 = 1000000000; long num2 = ...

2  TypesScript:Type '{}'は 'pick <t、k>'を入力するために割り当てられません、JavaScript `Pick`関数を正しく入力しますか?  ( Typescript type is not assignable to type pickt k how do i type java ) 
pick と呼ばれる関数を入力したい、私はTyptionScriptが組み込まれている<コード> Pick<T, K> を知っています。 Mが立ち往生しています。 指定された文字列に基づいて、 pick のプロパティを与えられた <ListView Name...

7  先行ゼロを持つことがある文字列から数字を解析する方法  ( How do i parse a number from a string that may have a leading zero ) 
Rubyでは、次の形式の日付を解析しています.24092008。 各セクション(年、月、日付)を数値に変換したいです。 私は、整数コンストラクターを通過する3つの文字列を生成する正規表現を使って分割しました。 <事前> <コード> date =~ /^(...

3  一度に複数のタイプが必要ですか?  ( Can you require multiple types at once ) 
基本的にこれをやりたい: <事前> <コード> public interface A { void a(); } public interface B { void b(); } public class SomeClass { pub...

793  タイプから新しいオブジェクトインスタンスを作成する方法  ( How to create a new object instance from a type ) 
は、コンパイル時にオブジェクトの Type を必ずしも知っているとは限りませんが、 Type のインスタンスを作成する必要があるかもしれません。 <コード> Type から新しいオブジェクトインスタンスを取得しますか? ...

15  Mathematicaの構造体データ型?  ( Struct data type in mathematica ) 
Mathematicaのシンボリックと数値機能で遊んだ後も、まともなプログラミング言語であると思います。ただし、汎用言語として魅力的に魅力的になることは、Cのような構造データ型(またはパスカルで知られているようなレコードタイプ)の欠如です。この問題を回避する...

82  署名付きの値で符号なし値を使用する場合は?  ( When to use unsigned values over signed ones ) 
署名付きの符号なしの変数を使用するのに適しているのはいつですか。 <コード> for ループの これについて多くの意見を聞いて、私は合意に似たものがあるかどうかを見たかったです。 <事前> <コード> for (unsigned int i = 0; i <...

1041  C ++のポッドの種類は何ですか?  ( What are pod types in c ) 
この用語の往復ポッドタイプに数回出会いました。 どういう意味ですか? ...

35  ANSI(C89 / 90)Cのバイトを表すために使用するタイプ?  ( Type to use to represent a byte in ansi c89 90 c ) 
ANSI(C89 / 90)Cのバイトを表す標準 - 不満の方法はありますか?私は、ほとんどの場合、Charがバイトであることを知っていますが、私の理解はこれが事件になることを保証されていないということです。また、C99規格にはSTDINT.Hがありますが、...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有