Mongodbチヌトシヌト電子商取匕、移行、䞀般的に䜿甚される操䜜、およびトランザクションに関するビット


この投皿は、小さなmongodbチヌトシヌトず、いく぀かのレシピを䜿甚したmongodb長いク゚リです。 小さなものが1か所に集められおいるず䟿利な堎合がありたすmongodb興味がある人mongodb誰でも自分に圹立぀ものを芋぀けおください。


SQL vs. NOSQLトピックに関するホリバヌのキヌで投皿が認識されるこずは望たしくありたせん。 SQL vs. NOSQLそしお、どこにでも賛吊䞡論があるこずは明らかです。この堎合、それはどこかに少し助けになり、どこかにあなたが察凊しなければならなかったいく぀かの䟋になりたす。 mongo shellおよびpython䟋。


  1. mongodbの新しいバヌゞョンぞの移行
  2. 比范ク゚リず論理ク゚リ
  3. Mongodb、正芏衚珟、むンデックスなどでの党文怜玢
  4. 原子挔算子デヌタの倉曎
  5. Mongodbのトランザクションに぀いお少し
  6. Mongodbの集玄フレヌムワヌクずJOIN
  7. 䟋
  8. Python小さなサンドボックス


mongodbぞの移行


バヌゞョン2.6ぞ


バヌゞョン2.6のリリヌス埌、 mongodbは、デヌタベヌス、個々のコレクションにナヌザヌ暩限を割り圓おるための新しいシステムを远加したした。 そしお、それに応じお、曎新時にはこれを考慮に入れる必芁がありたす。


1バヌゞョン2.4からバヌゞョン2.6に切り替える必芁がありたす。 2.2から2.6ぞの2.2は機胜せず、䞋䜍互換性がないため、段階的に曎新する必芁がありたす。


実際、曎新自䜓


 apt-get update apt-get install mongodb-org 

2 2.6アップグレヌドした埌、 adminデヌタベヌスに移動しお、ドキュメントの互換性をチェックするいく぀かのコマンドを実行する必芁がありたす。


 use admin db.upgradeCheckAllDBs() 

3 mongodbバヌゞョン2.6以降、既に述べたように、読み取り、曞き蟌みなどのコレクションたでの圹割分mongodbおよびナヌザヌの蚭定暩限が出珟したため、これらの圹割を適宜蚭定する必芁がありたす。そうしないず、 authコマンドを実行できたせん。 。


 db.auth('admin','password') 

これを行うには、たずadminデヌタベヌスに「管理者」ナヌザヌを䜜成したす


 db.createUser({user:"admin", pwd:"passwd", roles:[{role:"userAdminAnyDatabase", db:"admin"}]}) 

4その埌、目的のベヌスに移動したす。このベヌスで䜜業を行い、接続したす。そこにナヌザヌを䜜成したす。


 use newdb db.createUser({user:"admin", pwd:"passwd", roles:[{role:"dbAdmin", db:"newdb"}]}) 

system.usersコレクションのadminデヌタベヌスにレコヌドが自動的に䜜成されたす
次のコマンドでデヌタベヌスナヌザヌを衚瀺できたす。


 db.runCommand( { usersInfo: [ { user: "admin", db: "newdb" } ], showPrivileges: true } ) 

たあ、このすべおの埌、オヌバヌロヌドするこずを忘れないでください。


 service mongod restart 

このバヌゞョンのubuntuでは、サヌビスはmongodbなくmongodず呌ばれ、 /etcの蚭定はmongod.confず呌ばれたす。これは、アップグレヌド䞭に混乱しないように䞋䜍互換性がないためです。


2.6から3.0バヌゞョン


新しいバヌゞョン3.0ずストレヌゞ゚ンゞンの革新的な倉曎に぀いおは、すでに倚くのこずが曞かれおいたす。繰り返したせん。


3.0アップグレヌドする前に3.0バヌゞョン2.6にゞャンプせずに順次アップグレヌドするこずをお勧めしたす。 それは2.2->2.4->2.6です。
最新バヌゞョンは2.6.5以䞊を掚奚したす。
ubuntuのむンストヌル自䜓ubuntuかなり暙準です
3番目のバヌゞョンのリポゞトリを远加したす。


 sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 7F0CEB10 echo "deb http://repo.mongodb.org/apt/ubuntu "$(lsb_release -sc)"/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list 

Ubuntu 15.04


 echo "deb http://repo.mongodb.org/apt/ubuntu trusty/mongodb-org/3.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-3.0.list 

むンストヌル


 apt-get update apt-get install -y mongodb-org 

各コンポヌネントに぀いお、むンストヌル䞭にバヌゞョンを瀺したす。


 apt-get install -y mongodb-org=3.0.2 mongodb-org-server=3.0.2 mongodb-org-shell=3.0.2 mongodb-org-mongos=3.0.2 mongodb-org-tools=3.0.2 

その埌


 service mongod stop service mongod start 

mongodbのバヌゞョンを芋おみたしょmongodb 。


 root@user-pc:~# mongo MongoDB shell version: 3.0.2 connecting to: test > db.version() 3.0.2 > 

バヌゞョン3堎合、すべおがうたくいったので、ストレヌゞを倉曎できたす。 デフォルトはMMAPv1です。


/etc/mongo.conf倉曎する/etc/mongo.confは、オプションを远加したす。


 storageEngine = wiredTiger 

新しいリポゞトリに関連する可胜なオプションの詳现に぀いおは、 こちらをご芧ください。
そしお、 /var/lib/mongodb空になるようにしたす。そうしないず、 mongodbは自然に起動したせん。その前に、すべおのデヌタベヌスに察しおmongodumpを実行する必芁がありたす


 service mongod restart 

ストレヌゞの゚ンゞンのバヌゞョンを確認したす。


 root@user-pc:/etc# mongo MongoDB shell version: 3.0.2 connecting to: test > db.serverStatus() 

もしstorageEngineならすべおがstorageEngineあればwiredTigerを探しおいたす。


 "storageEngine" : { "name" : "wiredTiger" } 

ここで、 adminを含むデヌタベヌスをむンポヌトする必芁がありたす


 mongorestore --port 27017 -d admin 

PyMongoの新機胜


デヌタベヌスの新しいバヌゞョンず䞀緒に、 Python PyMongo甚の新しいバヌゞョンのドラむバヌPyMongo 、いく぀かの叀いメ゜ッドが削陀されたした


 pip install -U pymongo 

デヌタベヌス自䜓を曎新しなくおも、すべおが以前のように機胜するわけではありたせん。 すぐに気づいたこずから


  1. ナニバヌサル化ず統䞀のために、メ゜ッドupdate_one, insert_many, find_one_and_delete 仕様に update_one, insert_many, find_one_and_deleteたした
  2. たた、統合のために、 MongoClientデヌタベヌスに残されたコネクタは1぀だけであり、 MongoClientから'slave_okay': Trueなどのオプション'slave_okay': True削陀されたした。 ReplicaSetConnectionずMasterSlaveConnection削陀されたした。 MongoReplicaSetClient 、互換性のためにしばらくの間残されおいたす。

䜿甚䟋


 >>> # Connect to one standalone, mongos, or replica set member. >>> client = MongoClient('mongodb://server') >>> >>> # Connect to a replica set. >>> client = MongoClient('mongodb://member1,member2/?replicaSet=my_rs') >>> >>> # Load-balance among mongoses. >>> client = MongoClient('mongodb://mongos1,mongos2') 

  1. copy_databaseメ゜ッドを削陀
  2. end_request()メ゜ッドはend_request()さend_request()代わりにclose()を䜿甚するこずをお勧めしたす。
  3. コミュニティの䞀郚は、 asyncioからの非同期プログラミングずasyncioネむティブサポヌトがあるこずを期埅しおいたしたが、残念ながら残念です。 asyncio甚の優れたモヌタヌドラむバヌがありたすが、残念ながら、 asyncio甚には、実隓的なasyncio-mongoドラむバヌのみが䞍十分に開発されおおり、 GridFSサポヌトがありたせGridFS

集蚈フレヌムワヌクでは、カヌ゜ルはresultではなくすぐに返されるようにresult 。

比范ク゚リず論理ク゚リ


$eq比范挔算子
$eq db.test.find({ field: <value> })同等です


 { _id: 1, item: { name: "ab", code: "123" }, qty: 15, tags: [ "A", "B", "C" ] } { _id: 2, item: { name: "cd", code: "123" }, qty: 20, tags: [ "B" ] } db.test.find( { qty: { $eq: 20 } } ) # db.test.find( { qty: 20 } ) db.test.find( { tags: { $eq: [ "A", "B" ] } } ) # : db.test.find( { tags: [ "A", "B" ] } ) 

$ gt以䞊
$gtは、フィヌルド倀が指定された倀より倧きい(>)文曞を遞択したす。


 db.test.find( { qty: { $gt: 10 } } ) 

$ gteは以䞊
$gteは、フィヌルドの倀が指定された倀以䞊(>=)ドキュメントを遞択したす。


 db.test.find( { qty: { $gte: 10 } } ) 

$ ltより小さい
$ltは、フィヌルドの倀が指定した(<)より小さいドキュメントを遞択(<)たす


 db.test.find( { qty: { $lt: 10 } } ) 

$ lte以䞋
$lteは、フィヌルド倀が指定した倀以䞋(<=)ドキュメントを遞択(<=)たす


 db.test.find( { qty: { $lte: 10 } } ) 

売り手の利益が100未満の堎合、プレミアムは無効です。


 db.test.update({ "vendor.profit": { $lte: 100 } }, { $set: { premium: 0 } }) 

$ neは等しくありたせん
$neは、フィヌルド倀が指定された倀ず等しくない(! =)文曞を遞択したす。


 db.test.find( { qty: { $ne: 10 } } ) 

゚ントリヌチェックで$


 { _id: 1, qty: 10, tags: [ "name", "lastname" ], } db.test.find({ tags: { $in: ["name", "lastname"] } } ) 

正芏衚珟の䟋


 db.test.find( { tags: { $in: [ /^be/, /^st/ ] } } ) 

$ nin非゚ントリチェック
$in同じ$inが、逆も同様で、配列に倀が欠萜しおいるこずを確認したす。


 db.test.find( { qty: { $nin: [ 5, 15 ] } } ) 

$たたは挔算子たたは
叀兞的な挔算子はいく぀かの倀を取り、それらの少なくずも1぀が条件に䞀臎するこずを確認したす。


 db.test.find( { $or: [ { quantity: { $lt: 10 } }, { price: 10 } ] } ) 

このク゚リでは、2぀のむンデックスをコンパむルするこずが提案されおいたす。


 db.test.createIndex( { quantity: 1 } ) db.test.createIndex( { price: 1 } ) 

フルテキスト怜玢で$or $text挔算子ず組み合わせお䜿甚​​する堎合、むンデックスが必芁です。


$および挔算子「and」
オペレヌタヌは、怜玢された文曞内にリストされおいるすべおの倀の存圚チェックしたす。


 db.test.find( { $and: [ { price:10 }, { check: true } } ] 

$or次の䟋


 db.test.find( { $and : [ { $or : [ { price : 50 }, { price : 80 } ] }, { $or : [ { sale : true }, { qty : { $lt : 20 } } ] } ] } ) 

吊定挔算子ではない
遞択内の条件に䞀臎するドキュメントがないこずを確認したす。


 db.test.find( { price: { $not: { $gt: 10 } } } ) 

正芏衚珟の䟋


 import re for no_docs in db.test.find( { "item": { "$not": re.compile("^p.*") } } ): print no_docs 

$たたは挔算子not or


 db.test.find( { $nor: [ { price: 10 }, { qty: { $lt: 20 } }, { sale: true } ] } ) 

テストコレクション内のこのク゚リは、次のドキュメントを怜玢したす。



$はフィヌルドの存圚をチェックしお存圚したす
$existsは、特定のキヌが存圚するか存圚しないドキュメントを取埗したす。
パラメヌタfalseずしお$existsを指定$existsず、リク゚ストはqtyキヌが定矩されおいないドキュメントを返したす。


 db.test.find( { qty: { $exists: true } } ) 

$タむプBSONタむプチェック


 db.test.find( { field: { $type: -1 } } ); 

可胜なタむプ
皮類数泚釈
ダブル1
ひも2
察象3
配列4
バむナリデヌタ5
未定矩6非掚奚。
オブゞェクトID7
ブヌル倀8
日付9
ヌル10
正芏衚珟11
Javascript13
蚘号14
JavaScriptスコヌプ付き15
32ビット敎数16
タむムスタンプ17
64ビット敎数18
最小キヌ255-1を䜿甚したク゚リ。
最倧キヌ127

$ mod
$mod挔算子は、倀が最初の匕数で陀算され、陀算の残りが2番目の匕数に等しいフィヌルドを遞択するために䜿甚されたす。
たずえば、ドキュメントがありたす


 { "_id" : 1, "item" : "aa123", "qty" : 0 } { "_id" : 2, "item" : "bb123", "qty" : 7 } { "_id" : 3, "item" : "cc123", "qty" : 15 } 

リク゚スト


 db.test.find( { qty: { $mod: [ 5, 0 ] } } ) 

次のドキュメントを返したす。


 { "_id" : 1, "item" : "aa123", "qty" : 0 } { "_id" : 3, "item" : "cc123", "qty" : 15 } 

SQLからのアナログ


 select * from t where qty % 5 = 0; 

C 2.6バヌゞョンでは、1぀の芁玠のみを転送するこずは犁じられおおり、゚ラヌが返されたす。 たた、3぀以䞊の匕数を枡すず、゚ラヌも生成されたす。以前のバヌゞョンでは、䜙分な匕数は単に無芖されおいたした。
すべお遞択すべお䞀臎
配列の耇数の芁玠を䜜成したす。


 db.test.find( { tags: { $all: [ "python", "mongodb", "javascript" ] } } ) 

$ elemMatch
同じサブドキュメントに属する2぀以䞊の属性を比范する必芁がある堎合に䜿甚したす。
配列内にすべおの条件に䞀臎する芁玠があるこずを確認したす。


 { _id: 1, results: [ 82, 85, 88 ] } { _id: 2, results: [ 75, 88, 89 ] } db.test.find( { results: { $elemMatch: { $gte: 80, $lt: 85 } } } ) 

結果が埗られたす。


 { _id: 1, results: [ 82, 85, 88 ] } 

別の䟋


 { _id: 1, results: [{ product: "abc", score: 10 }, { product: "xyz", score: 5}] } { _id: 2, results: [{ product: "abc", score: 8 }, { product: "xyz", score: 7}] } { _id: 3, results: [{ product: "abc", score: 7 }, { product: "xyz", score: 8}] } >db.test.find( { results: { $elemMatch: { product: "xyz", score: { $gte: 8 } } } } ) { "_id": 3, "results": [{ "product": "abc", "score": 7 }, { "product": "xyz", "score": 8 } ] } 

配列の長さによる$サむズの怜玢
$size挔算子は、配列内の芁玠の数が$size倀に等しいドキュメントを怜玢したす。 たずえば、laguages配列に2぀の芁玠があるすべおのドキュメントを抜出したす。


 db.persons.find ({languages: {$size:2}}) 

このようなリク゚ストは、たずえば次のドキュメントに察応したす。


 {"name": "Alex", "age": "32", languages: ["python", "mongodb"]} 

$䜍眮挔算子
$はさたざたな堎合に䜿甚できたす。 配列の倀がどのむンデックスの䞋にあるのかわからないが、それを䜿甚したい堎合は、「䜍眮挔算子」を䜿甚したす
たずえば、ドキュメントがありたす


 { "_id" : 3, "semester" : 1, "grades" : [ 85, 100, 90 ] } { "_id" : 4, "semester" : 2, "grades" : [ 79, 85, 80 ] } 

そしお、それらを怜玢した埌、ドキュメント党䜓ではなく、ク゚リに察応する1぀の倀のみが衚瀺されるようにしたすが、事前にどの倀が存圚するかはわかりたせん。


 >db.test.find( { semester: 1, grades: { $gte: 85 } }, { "grades.$": 1 } ) { "_id" : 3, "grades" : [ 85 ] } 

曎新の䟋


 db.test.update( { _id: 22 } , { $set: { "array.$.name" : "alex" } } ) 

$スラむスは範囲を芋぀ける
$slice配列に保存されおいる倀の範囲を怜玢したす。
最初の10個のむベントを芋぀けたす。


 db.test.find( { }, { "events" : { $slice: 10 } } ) 

過去10件のむベントを怜玢


 db.test.find( { }, { "events" : { $slice: -10 } } ) 

Mongodb、正芏衚珟、むンデックスなどでの党文怜玢


Habréには、mongodb`の 優れた出版物がありたしたが、それ以来、新しい挔算子ず新しい機胜が远加されたした。
テキスト怜玢はむンデックスなしでは機胜しないため、それらに぀いお説明したしょう。
任意のテキストフィヌルドたたは配列に察しお単玔なむンデックスが䜜成されたす。

 db.test.createIndex( { title: "text", content: "text" } ) 

フィヌルド名たたはワむルドカヌド修食子を䜿甚できたす。


 db.text.createIndex( { "$**": "text" } ) 

党文怜玢甚のむンデックスを䜜成する堎合、英語でない堎合は蚀語を考慮する必芁がありたす。


 db.test.createIndex( { content : "text" }, { default_language: "russian" } ) 

バヌゞョン2.6以降、倚くの蚀語のテキストむンデックスを䞀床に蚭定できるようになりたした。


玢匕を䜜成できる略語を含む組み蟌み蚀語。
  • ダたたはデンマヌク語
  • nlたたはオランダ語
  • enたたは英語
  • fiたたはフィンランド語
  • frたたはフランス語
  • デたたはドむツ語
  • 胡たたはハンガリヌ人
  • それたたはむタリア語
  • nbたたはノルりェヌ語
  • ptたたはポルトガル語
  • roたたはルヌマニア語
  • ruたたはロシア語
  • esたたはスペむン語
  • svたたはスりェヌデン語
  • trたたはトルコ語

MongoDBは、むンデックスの䜜成時にドキュメントで指定された蚀語を䜿甚したす。 ドキュメントで指定された蚀語は、デフォルトの蚀語をオヌバヌラむドしたす。 埋め蟌みドキュメントの蚀語は、むンデックスの他のすべおをオヌバヌラむドしたす。


 { _id: 1, language: "portuguese", original: "A sorte protege os audazes.", translation: [ { language: "english", quote: "Fortune favors the bold." }, { language: "russian", quote: "  ." } ] } 

たた、 language_overrideパラメヌタヌを䜿甚しおlanguage_overrideフィヌルドを指定するこずもできたす。
たずえば、ドキュメントの堎合


 { _id: 2, idioma: "english", quote: "Fortune favors the bold." } { _id: 3, idioma: "russian", quote: "  ." } 

むンデックスは次のようになりたす。


 db.text.createIndex( { quote : "text" }, { language_override: "idioma" } ) 

むンデックスには、たずえば次のような特別な名前{ name: "name" }割り圓おるこずができたす。


 db.text.createIndex( { content: "text", "users.title": "text" }, { name: "text_Index" } ) 

この名前は、むンデックスの削陀に䜿甚するず䟿利です。


 db.text.dropIndex("text_Index") 

たた、テキストむンデックスの堎合、怜玢するフィヌルドの重芁床、重みを蚭定できたす。
たずえば、次のフィヌルドに重みを蚭定したす content - 10 、 keywords - 5 、およびtitle - 1 。


 db.test.createIndex( { content: "text", tags: "text", title: "text" }, { weights: { content: 10, tags: 5, }, name: "TextIndex"} ) 

むンデックスを䜿甚しお、出力のレコヌド数を制限できたす。


 { _id: 1, dept: "one", content: "red" } { _id: 3, dept: "one", content: "red" } { _id: 2, dept: "two", content: "gren" } db.test.createIndex( { dept: 1, content: "text" } ) db.test.find( { dept: "one", $text: { $search: "green" } } ) 

むンデックスに制限があるため、出力は2぀ではなく1぀のドキュメントになりたす。
Pythonサンプルむンデックス


 #PyMongo db.text.ensure_index( [ ('descr', "text" ), ( 'title.ru', "text" ) ], default_language="russian", name="full_text") 

テキスト怜玢

mongodbでテキスト怜玢が衚瀺された盎埌に、runCommandを䜿甚しお実行されたした。次に䟋を瀺したす。


 db.collection.runCommand( "text", { search: "" } ) 

ただし、バヌゞョン2.6以降、新しい挔算子$ text
単䞀単語怜玢


 db.articles.find( { $text: { $search: "coffee" } } ) 

耇数単語怜玢


 db.articles.find( { $text: { $search: "bake coffee cake" } } ) 

フレヌズで怜玢


 db.articles.find( { $text: { $search: "\"coffee cake\"" } } ) 

怜玢からフィヌルドを陀倖-


 db.articles.find( { $text: { $search: "bake coffee -cake" } } ) 

たた、 mongodb 2.6では、別の$メタ挔算子が衚瀺され、リク゚ストず䞀臎する結果の粟床が瀺されたした。


 db.text.insert([ { "_id": 4, "descr" : "  " }, { "_id": 3, "descr" : "    -" }, { "_id":6, "descr" : "  " }, { "_id":7, "descr" : "   " }, { "_id":8, "descr" : "  " }, { "_id":9, "descr" : ",    " }, { "_id":10, "descr" : ",    " }, { "_id":11, "descr" : "   " } { "_id":12, "descr" : "  " }, { "_id":13, "descr" : " " }, ]) db.text.createIndex( { descr : "text" }, { default_language: "russian" } ) db.text.find( { $text: { $search: "" } }, { score: { $meta: "textScore" } }).sort( { score: { $meta: "textScore" } } ) { "_id" : 13, "descr" : " ", "score" : 0.75 } { "_id" : 4, "descr" : "  ", "score" : 0.6666666666666666 } { "_id" : 6, "descr" : "  ", "score" : 0.6666666666666666 } { "_id" : 12, "descr" : "  ", "score" : 0.6666666666666666 } 

ここで{ score: { $meta: "textScore" } }結果に含たれる倀に新しいフィヌルドを䜜成し、それが既に゜ヌトに関䞎しおいたす。
$ regexを怜玢
MongoDBはPerl互換の正芏衚珟を䜿甚したす。


 db.test.insert([ { "_id" : 1, "descr" : "abc123" }, { "_id" : 2, "descr" : "abc123" }, { "_id" : 3, "descr" : "eee789" } ]) db.test.find( { sku: { $regex: /^ABC/i } } ) { "_id" : 1, "sku" : "abc123", "description" : "Single line description." } { "_id" : 2, "sku" : "abc123", "description" : "Single line description." } 

i倧文字ず小文字を区別したせん。
PostgreSQLアナログ


 select title from article where title ~ '^a' 'abc' 

原子挔算子デヌタの倉曎


通垞、これらの修食子はすべお、 db.test.update()およびdb.test.findAndModify()曎新操䜜に䜿甚されたす


$ inc increment
指定された倀だけフィヌルドを増枛したす。


 db.test.update( { _id: 1 }, { $inc: { qty: -2, "orders": 1 } } ) 

$乗数の増分
フィヌルド倀に指定された倀を乗算したす。


 { _id: 5, item: "mac", price: 10 } db.test.update({ _id: 1 }, { $mul: { price: 2 } } ) { _id: 5, item: "mac", price : 20 } 

$名前フィヌルドの名前倉曎


 { "_id": 1, "name": "alex" } db.test.update( { _id: 1 }, { $rename: { 'name': 'alias'} } ) { "_id": 1, "alias": "alex" } 

$ setはフィヌルドの倀を倉曎したす
これはおそらくupdate䜿甚される䞻な倉曎挔算子です。 倚くの堎合、mongodbのコンテキストでの単玔なトランザクションずしお蚘憶されたす。


 db.test.save({ "_id":8, "qty":"", tags:"" }) db.test.update( { _id: 8 }, { $set: { qty: 100, tags: [ "linux", "ubuntu"] } }) { "_id" : 8, "qty" : 100, "tags" : [ "linux", "ubuntu" ] } 

$ setOnInsertは、新しいドキュメントにフィヌルドを远加したす
update 3番目の匕数は、オプション{ upsert: true }これは、倉曎のドキュメントが芋぀からなかった堎合、新しいドキュメントを䜜成するこずを意味したす。 たた、 $setOnInsertオプションは、そこに挿入するフィヌルドを$setOnInsertたす。


 >db.test.update( { _id: 7 }, { $set: { item: "windows" }, $setOnInsert: { os: 'bad' } }, { upsert: true } ) { "_id" : 7, "item" : "windows", "os" : "bad" } 

$setを実行するフィヌルドは、新しく䜜成されたドキュメントにも衚瀺されたす。
$ unsetはキヌを削陀したす


 { "_id" : 8, "qty" : 100, "tags" : [ "linux", "ubuntu" ] } db.test.update( { _id: 8 }, { $unset: { qty: "", tags: "" } } ) { "_id" : 8 } 

最小の堎合、最小曎新
$minはフィヌルドを曎新したす。指定された倀がフィヌルドの珟圚の倀より小さい堎合、 $minは異なるタむプの倀を比范できたす。


 > db.test.save({ _id: 9, high: 800, low: 200 }) > db.test.update( { _id:9 }, { $min: { low: 150 } } ) >db.test.findOne({_id:9}) { "_id" : 9, "high" : 800, "low" : 150 } 

$ maxアップデヌト
$maxは、指定された倀がフィヌルドの珟圚の倀より倧きい堎合にフィヌルドを曎新したす。


 > db.test.save({ _id: 9, high: 800, low: 200 }) > db.test.update( { _id:9 }, { $max: { high: 900 } } ) > db.test.findOne({_id:9}) { "_id" : 9, "high" : 900, "low" : 200 } 

$ currentDateは珟圚の日付を蚭定したす
フィヌルドの倀を珟圚の日付に蚭定したす。


 > db.test.save({ _id:11, status: "init", date: ISODate("2015-05-05T01:11:11.111Z") }) > db.test.update( { _id:12 }, { $currentDate: { date: true } } ) > db.test.findOne({_id:12}) { "_id" : 12, "status" : "a", "date" : ISODate("2015-05-10T21:07:31.138Z") } 

配列の倉曎

$ addToSetが倀を远加しない堎合
配列に倀がただない堎合は倀を远加し、倀がある堎合は䜕もしたせん。


 db.test.save({ _id:1, array: ["a", "b"] }) db.test.update( { _id: 1 }, { $addToSet: {array: [ "c", "d" ] } } ) { "_id" : 1, "array" : [ "a", "b", [ "c", "d" ] ] } db.test.update( { _id: 1 }, { $addToSet: {array: "e" } } ) { "_id" : 1, "array" : [ "a", "b", [ "c", "d" ], "e" ] } 

$ popは最初たたは最埌を削陀したす
配列の最初たたは最埌の芁玠を削陀したす。 -1が指定されおいる堎合、最初の芁玠が削陀され、1が指定されおいる堎合、最埌の芁玠が削陀されたす。


 > db.test.save({ _id: 1, scores: [ 6, 7, 8, 9, 10 ] }) { "_id" : 1, "scores" : [ 6, 7, 8, 9, 10 ] } > db.test.update( { _id: 1 }, { $pop: { scores: -1 } } ) > db.test.findOne({_id:1}) { "_id" : 1, "scores" : [ 7, 8, 9, 10 ] } > db.test.update( { _id: 1 }, { $pop: { scores: 1 } } ) > db.test.findOne({_id:1}) { "_id" : 1, "scores" : [ 7, 8, 9 ] } 

$ pullAllは、指定されたすべおを削陀したす
指定されたすべおの芁玠を配列から削陀したす。


 { _id: 1, scores: [ 0, 2, 5, 5, 1, 0 ] } db.test.update( { _id: 1 }, { $pullAll: { scores: [ 0, 5 ] } } ) { "_id" : 1, "scores" : [ 2, 1 ] } 

芁求に応じお$プル削陀


 { _id: 1, votes: [ 3, 5, 6, 7, 7, 8 ] } > db.test.update( { _id: 1 }, { $pull: { votes: { $gte: 6 } } } ) { _id: 1, votes: [ 3, 5 ] } 

$ pushは倀を远加したす
配列に倀を远加したす。


 db.test.update( { _id: 1 }, { $push: { scores: 100} } ) 

$pushAll


$ pushの修食子

䞀床にたくさん
リストされた各アむテムを配列に远加したす。
たずえば、これを行う堎合 { $push: { scores: [ 2, 10 ] } }
その堎合、出力は次のような配列になりたす "scores" : [7, 8, 9, 90, 92, 85, [ 2, 10 ] ]
぀たり、配列である芁玠がもう1぀远加されたす。
そしお、 $eachを介しお、リストの各芁玠が配列の芁玠ずしお远加される堎合


 > db.test.update( { _id: 1 }, { $push: {scores: { $each: [ 90, 92, 85 ] } } } ) {"_id" : 1, "scores" : [7, 8, 9, 90, 92, 85, 2, 10 ] } 

$ pushを䜿甚する堎合、$スラむスはアむテム数を制限したす
$push貌り付けるずきに配列芁玠の数を制限したす。 必然的に$eachを䜿甚したす$eachそれなしで䜿甚しようずするず、゚ラヌが返されたす。


 { "_id" : 1, "scores" : [ 10, 20, 30 ] } > db.test.update( { _id: 1 }, { $push: { scores: { $each: [50, 60, 70], $slice: -5 } } } ) { "_id" : 1, "scores" : [ 20, 30, 50, 60, 70 ] } 

$sliceは20の最初の芁玠を切り取りたす。 -5なく5指定した堎合、最埌の芁玠70返されたす。


$ sort sort配列芁玠
指定されたフィヌルドに埓っお配列の芁玠を゜ヌトしたす。 $each挔算子$eachを䜿甚するこずも必須です。 挿入せずに䞊べ替える必芁がある堎合は、 $eachを空癜のたたにするこずができたす。


 { "_id" : 2, "tests" : [ 80, 70, 80, 50 ] } > db.test.update( { _id: 2 }, { $push: { tests: { $each: [40, 60], $sort: 1 } } }) { "_id" : 2, "tests" : [ 40, 50, 60, 70, 80, 80 ] } 

別の䟋


 db.test.update( { _id: 1 }, { $push: { field: { $each: [ ], $sort: { score: 1 } } } }) { "_id" : 1, "field" : [ { "id" : 3, "score" : 5 }, { "id" : 2, "score" : 6 }, { "id" : 1, "score" : 7 }, ] } 

$䜍眮は挿入䜍眮を瀺したす
倀を挿入する配列芁玠のカりントを瀺したす。


 { "_id" : 1, "scores" : [ 100 ] } db.test.update({ _id: 1 }, {$push: { scores: { $each: [50, 60, 70], $position: 0 } } }) { "_id" : 1, "scores" : [ 50, 60, 70, 100 ] } 

$ビットはビットごずに曎新されたす
ビット単䜍のフィヌルド曎新を実行したす。 挔算子はビット単䜍のand 、 orおよびxorサポヌトしたす。


 { "_id" : 1, "expdata" : 13 } > db.bit.update({_id:1}, {$bit:{expdata:{and:NumberInt(10)} } } ) { "_id" : 1, "expdata" : 8 } 

$分離-霧化
たずえば、曎新操䜜が行われおいる間、ドキュメントを読み取りおよび曞き蟌み甚にロックしたす。
削陀時に$isolatedれた$isolated䜿甚


 db.test.remove( { temp: { $lt: 10 }, $isolated: 1 } ) 

曎新時に$isolatedた$isolatedを䜿甚


 db.test.update( {status: "init" , $isolated: 1 }, { $inc: { count : 1 }}, {multi: true } ) 

$分離は、シャヌドクラスタヌでは機胜したせん
バヌゞョン2.2  $isolated挔算子が$atomic眮き換わりたした


mongodbのトランザクション、䞀意のむンデックス、2フェヌズコミットに぀いお


圓然、 MongoDB PostgreeSQLような埓来のSQL゜リュヌションのようなPostgreeSQLはそうではなく、おそらく䞍可胜です。 もしそうなら、それはむしろ、完党な正芏化ず敎合性制埡を備えたリレヌショナルデヌタベヌスになりたす。
したがっお、 mongoDBトランザクションに぀いお説明する堎合、原則ずしお、 update()およびfindAndModify()で䞀意のむンデックスず組み合わせお䜿甚​​されるタむプ$setアトミック操䜜を意味したす。 耇数のデヌタベヌス内でトランザクションを確保する必芁がある堎合、リレヌショナルデヌタベヌスで䞀般的な2フェヌズコミットも同様です。


䞀意のむンデックス


mongodbの䞀意のむンデックスにより、むンデックスフィヌルドの重耇倀を含むすべおのドキュメントが拒吊されたす。


 db.test.createIndex( { "user_id": 1 }, { unique: true } ) 

コレクションがありたすNikず呌びたしょう。このコレクションには、 nameフィヌルドの倀がNikドキュメントはありたせん。 耇数のクラむアントが{ upsert: true }パラメヌタヌを䜿甚しおこのドキュメントを同時に曎新しようずしおいるず仮定したす条件によっお、曎新するドキュメントが存圚しない堎合、䜜成する必芁があるこずを意味したす。
䟋


 db.test.update( { name: "Nik" }, { name: "Nik", vote: 1 }, { upsert: true } ) 

update() , , , .


, . . , .


unique false MongoDB



, A B .
:



accounts transactions
accounts


 db.accounts.insert( [ { _id: "A", balance: 1000, pendingTransactions: [] }, { _id: "B", balance: 1000, pendingTransactions: [] } ] ) 

transactions .


 db.transactions.insert({ _id: 1, source: "A", destination: "B", value: 100, state: "initial", lastModified: new Date()}) 

:



1)
, initial . t


 > var t = db.transactions.findOne( { state: "initial" } ) > t { "_id" : 1, "source" : "A", "destination" : "B", "value" : 100, "state" : "initial", "lastModified" : ISODate("2015-05-26T16:35:54.637Z") } 

2) pending
initial pending .


 > db.transactions.update( { _id: t._id, state: "initial" }, { $set: { state: "pending" }, $currentDate: { lastModified: true } } ) > db.transactions.find() { "_id" : 1, "source" : "A", "destination" : "B", "value" : 100, "state" : "pending", "lastModified" : ISODate("2015-05-26T17:02:19.002Z") } > 

3)
, , value , pendingTransactions _id ( ).


 > db.accounts.update( { _id: t.source, pendingTransactions: { $ne: t._id } }, { $inc: { balance: -t.value }, $push: { pendingTransactions: t._id } } ) > db.accounts.update( { _id: t.destination, pendingTransactions: { $ne: t._id } }, { $inc: { balance: t.value }, $push: { pendingTransactions: t._id } } ) > db.accounts.find() { "_id" : "A", "balance" : 900, "pendingTransactions" : [ 1 ] } { "_id" : "B", "balance" : 1100, "pendingTransactions" : [ 1 ] } 

4) applied
.


 > db.transactions.update( { _id: t._id, state: "pending" }, { $set: { state: "applied" }, $currentDate: { lastModified: true } } ) > db.transactions.find() { "_id" : 1, "source" : "A", "destination" : "B", "value" : 100, "state" : "applied", "lastModified" : ISODate("2015-05-26T17:13:15.517Z") } 

5) _id
pendingTransactions : _id pendingTransactions .


 > db.accounts.update( { _id: t.source, pendingTransactions: t._id }, { $pull: { pendingTransactions: t._id } } ) > db.accounts.update( { _id: t.destination, pendingTransactions: t._id }, { $pull: { pendingTransactions: t._id } } ) > db.accounts.find() { "_id" : "A", "balance" : 900, "pendingTransactions" : [ ] } { "_id" : "B", "balance" : 1100, "pendingTransactions" : [ ] } 

6) done
.


 > db.transactions.update( { _id: t._id, state: "applied" }, { $set: { state: "done" }, $currentDate: { lastModified: true } } ) > db.transactions.find() { "_id" : 1, "source" : "A", "destination" : "B", "value" : 100, "state" : "done", "lastModified" : ISODate("2015-05-26T17:22:22.194Z") } 


. .
1) canceling
, , canceling .


 db.transactions.update( { _id: t._id, state: "pending" }, {$set: { state: "canceling" }, $currentDate: { lastModified: true }} ) > db.transactions.find() { "_id" : 1, "source" : "A", "destination" : "B", "value" : 100, "state" : "canceling", "lastModified" : ISODate("2015-05-26T18:29:28.018Z") } 

2)
.


 > db.accounts.update( { _id: t.destination, pendingTransactions: t._id }, { $inc: { balance: -t.value }, $pull: { pendingTransactions: t._id } } ) > db.accounts.update( { _id: t.source, pendingTransactions: t._id }, { $inc: { balance: t.value}, $pull: { pendingTransactions: t._id } } ) > db.accounts.find() { "_id" : "A", "balance" : 1000, "pendingTransactions" : [ 1 ] } { "_id" : "B", "balance" : 1000, "pendingTransactions" : [ 1 ] } > 

3) cancelled
.


 db.transactions.update( { _id: t._id, state: "canceling" }, { $set: { state: "cancelled" }, $currentDate: { lastModified: true } } ) > db.transactions.find() { "_id" : 1, "source" : "A", "destination" : "B", "value" : 100, "state" : "cancelled", "lastModified" : ISODate("2015-05-26T19:14:11.830Z") } 


, . .
findAndModify() , :


 t = db.transactions.findAndModify({ query: { state: "initial", application: { $exists: false } }, update: {$set: { state: "pending", application: "App1"}, $currentDate:{ lastModified: true }}, new: true }) 

6. JOIN-


JOIN - mongo , - . stackoverflow , , .


, , , , .


- , , { type: 'news' } .


, , .


, , aggregation framework . pipeline . , , , , , ..


, , .


 db.test.insert([ { "_id":"gomer", "type":"user", "group":["user", "author"] }, { "_id":"vasya", "type":"user", "group":["user"] } ]) 

.


 db.test.insert([ { "_id": 1, "type": "blogs", "user": "gomer", "article": "aaa" }, { "_id": 2, "type": "blogs", "user": "vasya", "article": "bbb" }, { "_id": 3, "type": "blogs", "user": "gomer", "article": "ccc" } ]) 

, . , .


, , , "".


 users = [doc._id for doc in db.test.find({"type":'user', 'group': {'$all': ['author']}})] articles = db.test.find({"type": "blogs", "user": {'$in': users}) 

c SQL :


 SELECT blogs.* FROM blogs, user, usergroup, group WHERE blogs.user = user.id AND usergroup.user = user.id AND usergroup.group = group.id AND group.name = 'author'; 

user, d jsonb. — :


 SELECT blogs.* FROM blogs, user WHERE blogs.user = user.id AND user.group ? 'author'; SELECT blogs.* FROM (SELECT * FROM test WHERE d->type = 'blogs') blogs, (SELECT * FROM test WHERE d->type = 'user') user WHERE blogs.d->user = user.id AND user.d->group ? 'author'; 

pipe.


 db.test.aggregate([ { $match: { $or: [ {type: "blogs"}, {type: "user"} ] } }, { $project: { a: 1, blogs: { $cond: { if: { type: '$blogs'}, then: {_id:"$_id", user:"$user", article:"$article"}, else: null } }, user: { $cond: { if: { type: '$user' }, then: { _id:"$_id", group:"$group"}, else: null } } } }, { $group : { _id : { a: "$a" }, user: { $push: "$user" }, blog: { $push: "$blogs" }, } }, { $unwind : "$blog" }, { $unwind : "$user" }, { $project:{ user: "$user", article: "$blog", matches: { $eq:[ "$user._id", "$blog.user" ] } } }, { $match: { matches: true } } ]) 

. 7 .
, mongodb pipeline . , , , , , .


SQL Terms, Functions, and ConceptsMongoDB Aggregation Operators
WHERE$match
GROUP BY$group
HAVING$match
SELECT$project
ORDER BY$sort
LIMIT$limit
SUM()$sum
COUNT()$sum
join$unwind

.


 > db.ag.aggregate([ { $match: {$or:[{type:"blogs"},{type:"user"}]} } ]) { "_id" : "gomer", "type" : "user", "group" : [ "user", "author" ] } { "_id" : "vasya", "type" : "user", "group" : [ "user" ] } { "_id" : 1, "type" : "blogs", "user" : "gomer", "article" : "aaa" } { "_id" : 2, "type" : "blogs", "user" : "vasya", "article" : "bbb" } { "_id" : 3, "type" : "blogs", "user" : "gomer", "article" : "ccc" } 

$match find() , , .
c $project , blogs users . 2.6 $cond . blogs users , .


 db.test.aggregate([ { $match: {$or:[ { type:"blogs"}, { type: "user"} ] } }, { $project: { a: 1, blogs: { $cond: { if: {type: '$blogs'}, then: {_id:"$_id", user:"$user", article:"$article"}, else: null } }, user: { $cond: { if: { type: '$user'}, then: {_id:"$_id", group:"$group"}, else: null } } } } ]) { "_id": "gomer", "blogs": { "_id" : "gomer" }, "user": { "_id": "gomer", "group": [ "user", "author" ] } } { "_id": "vasya", "blogs": { "_id" : "vasya" }, "user" : { "_id" : "vasya", "group": [ "user" ] } } { "_id": 1, "user": { "_id": 1 }, "blogs" : { "_id": 1, "user": "gomer", "article": "aaa" } } { "_id": 2, "user": { "_id": 2 }, "blogs" : { "_id": 2, "user": "vasya", "article": "bbb" } } { "_id": 3, "user": { "_id": 3 }, "blogs" : { "_id": 3, "user": "gomer", "article": "ccc" } } 

:


 ...{ $group : { _id : { a: "$a" }, user: { $push: "$user" }, blog: { $push: "$blogs" }, } }... { "_id" : { "a" : null }, "user": [ { "_id": "gomer", "group": [ "user", "author" ] }, { "_id": "vasya", "group": [ "user" ] }, { "_id": 1 }, { "_id": 2 }, { "_id": 3 } ], "blog": [ { "_id": "gomer" }, { "_id": "vasya" }, { "_id": 1, "user": "gomer", "article": "aaa" }, { "_id": 2, "user": "vasya", "article": "bbb" }, { "_id": 3, "user": "gomer", "article": "ccc"} ] } 

$unwind
 ....{ $unwind : "$blog" }, { $unwind : "$user" } .... { "_id": { "a":null }, "user": { "_id": "gomer", "group": [ "user", "author" ] }, "blog": { "_id": "gomer" } } { "_id": { "a":null }, "user": { "_id": "vasya", "group": [ "user" ] }, "blog" : { "_id": "gomer" } } { "_id": { "a":null }, "user": { "_id": 1 }, "blog": { "_id" : "gomer" } } { "_id": { "a" : null }, "user" : { "_id" : 2 }, "blog" : { "_id" : "gomer" } } { "_id": { "a" : null }, "user" : { "_id" : 3 }, "blog" : { "_id" : "gomer" } } { "_id": { "a": null }, "user": { "_id": "gomer", "group" : [ "user", "author" ] }, "blog": { "_id": "vasya"}} { "_id": { "a" : null }, "user" : { "_id" : "vasya", "group" : [ "user" ] }, "blog" : { "_id" : "vasya" } } { "_id": { "a" : null }, "user" : { "_id" : 1 }, "blog" : { "_id" : "vasya" } } { "_id": { "a" : null }, "user" : { "_id" : 2 }, "blog" : { "_id" : "vasya" } } { "_id": { "a" : null }, "user" : { "_id" : 3 }, "blog" : { "_id" : "vasya" } } { "_id": { "a" : null }, "user" : { "_id" : "gomer", "group" : [ "user", "author" ] }, "blog" : { "_id" : 1, "user": "gomer", "article" : "aaa" } } { "_id": { "a" : null }, "user": { "_id" "vasya", "group": [ "user" ] }, "blog": { "_id": 1, "user": "gomer", "article": "aaa" } } { "_id": { "a" : null }, "user" : { "_id" : 1 }, "blog" : { "_id" : 1, "user" : "gomer", "article" : "aaa" } } { "_id" : { "a" : null }, "user" : { "_id" : 2 }, "blog" : { "_id" : 1, "user" : "gomer", "article" : "aaa" } } { "_id": { "a" : null }, "user" : { "_id" : 3 }, "blog" : { "_id" : 1, "user" : "gomer", "article" : "aaa" } } { "_id": { "a" : null }, "user" : { "_id" : "gomer", "group" : [ "user", "author" ] }, "blog" : { "_id" : 2, "user": "vasya", "article" : "bbb" } } { "_id": { "a" : null }, "user" : { "_id" : "vasya", "group" : [ "user" ] }, "blog" : { "_id" : 2, "user" : "vasya", "article" : "bbb" } } { "_id": { "a" : null }, "user" : { "_id" : 1 }, "blog" : { "_id" : 2, "user" : "vasya", "article" : "bbb" } } { "_id": { "a" : null }, "user" : { "_id" : 2 }, "blog" : { "_id" : 2, "user" : "vasya", "article" : "bbb" } } { "_id": { "a" : null }, "user" : { "_id" : 3 }, "blog" : { "_id" : 2, "user" : "vasya", "article" : "bbb" } } 

, $eq:[ "$user._id", "$blog.user" ] "user" : { "_id" : 2 } "blog" : { "user" : "vasya" } .


 ...{ $project:{ user:"$user", article:"$blog", matches:{ $eq:[ "$user._id", "$blog.user" ] } } } ..... 

 { "_id" : { "a" : null }, "user" : { "_id" : 1 }, "article" : { "_id" : 1, "user" : "gomer", "article" : "aaa" }, "matches" : false } { "_id" : { "a" : null }, "user" : { "_id" : 2 }, "article" : { "_id" : 1, "user" : "gomer", "article" : "aaa" }, "matches" : false } { "_id" : { "a" : null }, "user" : { "_id" : 3 }, "article" : { "_id" : 1, "user" : "gomer", "article" : "aaa" }, "matches" : false } { "_id" : { "a" : null }, "user" : { "_id" : "gomer", "group" : [ "user", "author" ] }, "article" : { "_id" : 2, "user" : "vasya", "article" : "bbb" }, "matches" : false } { "_id" : { "a" : null }, "user" : { "_id" : "vasya", "group" : [ "user" ] }, "article" : { "_id" : 2, "user" : "vasya", "article" : "bbb" }, "matches" : true } { "_id" : { "a" : null }, "user" : { "_id" : 1 }, "article" : { "_id" : 2, "user" : "vasya", "article" : "bbb" }, "matches" : false } { "_id" : { "a" : null }, "user" : { "_id" : 2 }, "article" : { "_id" : 2, "user" : "vasya", "article" : "bbb" }, "matches" : false } { "_id" : { "a" : null }, "user" : { "_id" : 3 }, "article" : { "_id" : 2, "user" : "vasya", "article" : "bbb" }, "matches" : false } Type "it" for more 

:


 { $match: { matches:true } } 

{ "_id": { "a": null }, "user": { "_id": "gomer", "group": [ "user", "author" ] }, "article": { "_id": 1, "user": "gomer", "article": "aaa" }, "matches": true }
{ "_id": { "a": null }, "user": { "_id": "vasya", "group": [ "user" ] }, "article": { "_id": 2, "user": "vasya", "article": "bbb" }, "matches": true }
{ "_id": { "a": null }, "user": { "_id": "gomer", "group": [ "user", "author" ] }, "article": { "_id": 3, "user": "gomer", "article": "ccc" }, "matches": true }


, .
, .


, pipeline .


7.


, , . :



, Mongodb


, — . , , , .



.
:


 { _id:1, type:"blog", title:{ru:"O MongoDB", en:""}, comments: [ { _id: 1, title: "one", "user": "Alex", parent: "root", child: [2, 3]}, { _id: 2, title: "two", "user": "Serg", parent: 1 }, { _id: 3, title: "two", "user": "Andrey", parent: 1 } ] } 

:


 { _id: 1, type: "comment", title: "one", "user": "Alex", parent: "root", child: [ 2, 3 ] }, { _id: 2, type: "comment", title: "two", "user": "Serg", parent: 1 }, { _id: 3, type: "comment", title: "two", "user": "Andrey", parent: 1 } 

.
, .
, , "" .


.
:


 db.test.update( { _id: 1 }, { $pull: { child: 2 } } ) db.test.update( { _id: 1 }, { $pullAll: { child: [ 2, 3 ] } } ) 

:


 db.test.update( { _id: 1 }, { $push: { child: 2 } } } ) db.test.update( { _id: 1 }, { $push: { child: { $each: [ 2, 3 ] } } } ) 

:


 def getTree(docs): tree = { doc["_id"]: doc for doc in docs } for doc in docs: doc['child'] = [] for doc in docs: parent = doc["parent"] if parent != "root": tree[parent]["child"].append(doc) docs={"_id": "root", "child": [doc for doc in docs if doc['parent'] == "root" ]} return docs { _id: 1, type: "comment", title: "one", "user": "Alex", parent: "root", child: [ { _id: 2, type: "comment", title: "two", "user": "Serg", parent: 1 }, { _id: 3, type: "comment", title: "two", "user": "Andrey", parent: 1 } ] } 

, , , _id :


 def count(cls): db = connect() ctr = db.test.find({'type':'goods', 'class':cls}).count() childs = db.test.find_one({'_id':cls}) for res in childs['child']: ctr += count(res) return ctr 

, _id , :


 def path( id ): p = [] parent = db.test.find_one( {"_id": id }, { "parent": 1, "alias":1, "title":1}) else: path.append( ( parent['alias'], parent['title'] ) ) p += path( parent['parent'] ) return p print ( path("123") ) >>>[ ("one", " "), ("two", " ") ] 

,


, { tags : { ru: ", " } } , . { tags : [ "", "" ] } .
, .
, , , :


 { _id: 1, title: " ", tags: [ "php", "python" ] } db.test.find({ tags: { $in: ["php", "python" ] } } ) 

:



 dt = ( datetime.today() + timedelta( days = -5 ) ) db.test.aggregate([ { $match: { //       type: "news", date: { $gt: dt }, //   . vate: { $gte: 2 }, //   . user: { $in: [ "alex", "pavel" ] } $and: [ //      . { pub: true }, { accept: true }, //       . { tags: { $in: ["php", "python" ] } } , //        . { tags: { $nin: [""] } } ] }, //      . { $sort: {'primary': -1, view: -1}}, //   ,    5 { $limit:3}, //    1    ,   . { $group: { '_id':'$user', 'id': {'$first':'$_id'}, 'type':{'$first':'$type'}, 'title': {'$first':'$title'}, 'content':{'$first':'$content'}, 'count':{'$first':'$count_comm'}, 'last_comm':{'$first':'$last_comm'}, 'vote':{'$first':'$vote'}, 'tags':{'$first':'$tags'} } }, //       . { $project :{ '_id':'$id', 'title':1, 'content':1, 'type':1, 'count':1, 'last_comm':1, 'tags':1, 'vote':1 } } ]) 

 db.test.aggregate([ { $match: { type: "news", date: { $gt: dt }, vate: { $gte: 2 }, user: { $in: [ "alex", "pavel" ] } $and: [ { pub: true }, { accept: true }, { tags: { $in: ["php", "python" ] } } , { tags: { $nin: [""] } } ] }, { $sort: {'primary': -1, view: -1}}, { $limit:3}, { $group: {'_id':'$user', 'id': {'$first':'$_id'}, 'type':{'$first':'$type'}, 'title': {'$first':'$title'}, 'content':{'$first':'$content'}, 'count':{'$first':'$count_comm'}, 'last_comm':{'$first':'$last_comm'}, 'vote':{'$first':'$vote'}, 'tags':{'$first':'$tags'} } }, { $project :{ '_id':'$id', 'title':1, 'content':1, 'type':1, 'count':1, 'last_comm':1, 'tags':1, 'vote':1 } } ]) 

, — .


-commerce Mongodb


, - — - . , , , , , , .


, - , . .


, , , -.


  1. ( )
  2. .

, , , — . , , .


().


:


  1. , .
  2. .

, , . :


 cursor = db.test.find({ "type": "filters", "category": "id_category" }) 

, , , , .


=>
=> 15.6 , 17 .



, . . ., .
— , , — .



. , .


, , . .



, . _id .
$addToSet .


 db.test.aggregate([ //         id  { '$match': { type : "goods_attr", category: id_category } }, //       ,    { '$project': { "title" : "$title.ru", 'value': "$attr.ru", 'category': "$category", '_id': 0 } }, { '$group' : { '_id': { 'category' :"$category", 'title': "$title"} , 'filters': { '$addToSet': "$value" } } }, { '$group' : { '_id' :"$_id.category", 'title':{ '$addToSet': { 'title': "$_id.title", 'filters': "$filters" } } } } ]) 

group :


 ...{ '$group' : { '_id': { 'category' :"$category", 'title': "$title"} , 'filters': { '$addToSet': "$value" } } }.... { "_id": { "category": "id", "title": "   " }, "filters": [ "" ] } { "_id" : { "category" : "id", "title" : "" }, "filters" : [ " " ] } { "_id" : { "category" : "id", "title" : " " }, "filters" : [ "" ] } 

group .


 ...{ '$group' : { '_id':"$_id.category", 'title':{'$addToSet': {'title': "$_id.title", 'filters': "$filters" }} } ...} { "_id" : "id_category", "title" : [ { "title" : "   ", "filters" : [ "  ", "  ", " ", "  " ] }, { "title" : " ", "filters" : [ "" ] }, { "title" : "", "filters" : [ " " ] }, { "title" : "   ", "filters" : [ "" ] } ] } 

, , . , , owner_id _id .


 db.test.aggregate([ { '$match' : { 'type' : "goods_attr", "category'':"id", '$or': [ {'title': '', 'attr': ' '}, {'title': '   ', 'attr_val': '  '} ] } }, { '$group': {'_id': "$owner_id", "attr": { '$push': "$title" }}}, { '$match': {"attr": {'$all': [ '', '   ' ] }}}, { '$project': {"_id":1 } } ]) 

_id .


Python


.


, , , ( — ) . , , .


ERP . , , - . , , .


python , , .


exec


 src = ''' result = 0 for i in xrange(100): result += i ''' assert '__' not in src, 'Prohibited to use symbols "__"' pr = compile(src, '<string>', mode='exec') glob = { '__builtins__':{ 'xrange':xrange } } exec(pr, glob) print glob['result'] 

eval ( )


 src = 'max(5,7,3)' glob = { '__builtins__':{ 'max':max } } assert '__' not in src, 'Prohibited to use symbols "__"' print ( eval(src, glob) ) 

— :
assert '__' not in src, 'Prohibited to use symbols "__"'




Source: https://habr.com/ru/post/J259219/


All Articles