{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Pymongo - mongo in python\n",
    "To use python with mongo we need to use the pymongo package\n",
    " - install using `pip install pymongo`, or via the anaconda application"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Connecting\n",
    "To connect to our Database we need to instantiate a client connection. To do this wee need:\n",
    " - hostname or ip-address\n",
    " - port\n",
    " - username\n",
    " - password\n",
    " \n",
    "In addition we may sometimes need to provide an *authSource*. This simply tells Mongo where the information on our user exists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pymongo import MongoClient\n",
    "\n",
    "client = MongoClient(host='18.219.151.47', #host is the hostname for the database\n",
    "                     port=27017, #port is the port number that mongo is running on\n",
    "                     username='student', #username for the db\n",
    "                     password='emse6992pass', #password for the db\n",
    "                     authSource='emse6992') #Since our user only exists for the emse6992 db, we need to specify this\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "***NOTE: NEVER hard encode your password!!!***"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Verify the connection is working:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'version': '3.2.22',\n",
       " 'gitVersion': '105acca0d443f9a47c1a5bd608fd7133840a58dd',\n",
       " 'modules': [],\n",
       " 'allocator': 'tcmalloc',\n",
       " 'javascriptEngine': 'mozjs',\n",
       " 'sysInfo': 'deprecated',\n",
       " 'versionArray': [3, 2, 22, 0],\n",
       " 'openssl': {'running': 'OpenSSL 1.0.2g  1 Mar 2016',\n",
       "  'compiled': 'OpenSSL 1.0.2g  1 Mar 2016'},\n",
       " 'buildEnvironment': {'distmod': 'ubuntu1604',\n",
       "  'distarch': 'x86_64',\n",
       "  'cc': '/opt/mongodbtoolchain/v2/bin/gcc: gcc (GCC) 5.4.0',\n",
       "  'ccflags': '-fno-omit-frame-pointer -fPIC -fno-strict-aliasing -ggdb -pthread -Wall -Wsign-compare -Wno-unknown-pragmas -Winvalid-pch -Werror -O2 -Wno-unused-local-typedefs -Wno-unused-function -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-missing-braces -fno-builtin-memcmp',\n",
       "  'cxx': '/opt/mongodbtoolchain/v2/bin/g++: g++ (GCC) 5.4.0',\n",
       "  'cxxflags': '-Wnon-virtual-dtor -Woverloaded-virtual -Wno-maybe-uninitialized -std=c++11',\n",
       "  'linkflags': '-fPIC -pthread -Wl,-z,now -rdynamic -fuse-ld=gold -Wl,-z,noexecstack -Wl,--warn-execstack',\n",
       "  'target_arch': 'x86_64',\n",
       "  'target_os': 'linux'},\n",
       " 'bits': 64,\n",
       " 'debug': False,\n",
       " 'maxBsonObjectSize': 16777216,\n",
       " 'storageEngines': ['devnull', 'ephemeralForTest', 'mmapv1', 'wiredTiger'],\n",
       " 'ok': 1.0}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "client.server_info()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Accessing Databases and Collections\n",
    "Even if we have authenticated oursevles, we still need to tell Mongo what database and collections we are interested. Once connected those attributes are name addressable:\n",
    " - `conn['database_name']` or `conn.database_name`\n",
    " - `database['coll_name']` or `database.coll_name`"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Connecting to the Database:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "db = client.emse6992\n",
    "# db = client['emse6992'] - Alternative method"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Proof we're connected:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['places',\n",
       " 'twitter_lists',\n",
       " 'twitter_retweets',\n",
       " 'moviesdata',\n",
       " 'housingdata',\n",
       " 'restaurants',\n",
       " 'twitter_friends',\n",
       " 'twitter_favorites',\n",
       " 'test_collection',\n",
       " 'twitter_statuses']"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "db.list_collection_names()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Connecting to the Collections:**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "favs_coll = db.twitter_favorites\n",
    "# favs_coll = db['twitter_favorites']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Proof this works:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'_id': ObjectId('60064b31e991a9c376547e89'),\n",
       " 'created_at': datetime.datetime(2021, 1, 7, 20, 27, 25),\n",
       " 'favorite_count': 152,\n",
       " 'hashtags': [],\n",
       " 'id': 1347278689000513536,\n",
       " 'id_str': '1347278689000513536',\n",
       " 'in_reply_to_screen_name': 'elonmusk',\n",
       " 'in_reply_to_status_id': 1347278232077312000,\n",
       " 'in_reply_to_user_id': 44196397,\n",
       " 'lang': 'en',\n",
       " 'source': '<a href=\"http://twitter.com/download/iphone\" rel=\"nofollow\">Twitter for iPhone</a>',\n",
       " 'text': '@elonmusk @4thFromOurStar I think it’s Mars that is playing hard to get or hard to get to. 😉',\n",
       " 'urls': [],\n",
       " 'user': {'created_at': 'Sat Jun 22 20:20:09 +0000 2019',\n",
       "  'default_profile': True,\n",
       "  'description': 'Just a 17 year old Tesla Shareholder🚗🔋Everything Elon🧠❤️Astrophotography📸🚀#TeslaTeens ⚔️ FUTURE Cybertruck owner',\n",
       "  'favourites_count': 20585,\n",
       "  'followers_count': 2390,\n",
       "  'friends_count': 526,\n",
       "  'geo_enabled': True,\n",
       "  'id': 1142527715670519808,\n",
       "  'id_str': '1142527715670519808',\n",
       "  'listed_count': 27,\n",
       "  'location': 'Phoenix, AZ',\n",
       "  'name': 'jordan🚀',\n",
       "  'profile_background_color': 'F5F8FA',\n",
       "  'profile_banner_url': 'https://pbs.twimg.com/profile_banners/1142527715670519808/1603392699',\n",
       "  'profile_image_url': 'http://pbs.twimg.com/profile_images/1347136422466129923/j1jTp9My_normal.jpg',\n",
       "  'profile_image_url_https': 'https://pbs.twimg.com/profile_images/1347136422466129923/j1jTp9My_normal.jpg',\n",
       "  'profile_link_color': '1DA1F2',\n",
       "  'profile_sidebar_border_color': 'C0DEED',\n",
       "  'profile_sidebar_fill_color': 'DDEEF6',\n",
       "  'profile_text_color': '333333',\n",
       "  'profile_use_background_image': True,\n",
       "  'screen_name': 'AstroJordy',\n",
       "  'statuses_count': 7532,\n",
       "  'url': 'https://t.co/lg6SohofDL'},\n",
       " 'user_mentions': [{'id': 44196397,\n",
       "   'id_str': '44196397',\n",
       "   'name': 'Elon Musk',\n",
       "   'screen_name': 'elonmusk'},\n",
       "  {'id': 1091459141397180416,\n",
       "   'id_str': '1091459141397180416',\n",
       "   'name': 'Mars',\n",
       "   'screen_name': '4thFromOurStar'}],\n",
       " 'favorited_by_screen_name': '4thFromOurStar'}"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "doc = favs_coll.find_one({})\n",
    "doc"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "doc['favorited_by_screen_name']"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Querying\n",
    "Once connected, we are ready to start querying the database.\n",
    "\n",
    "The great thing about Python is it's integration with both JSON and Mongo, meaning that the Python Mongo API is almost exactly the same as Monog's own query API."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### find_one()\n",
    "This method works exactly the same as the Mongo equivelant. In addition the interior logic is a direct 1-to-1 with Mongo's"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "scrolled": true
   },
   "outputs": [],
   "source": [
    "doc = favs_coll.find_one({\"favorited_by_screen_name\": \"elonmusk\"})\n",
    "doc"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## In Class Excercise:\n",
    "Using the **twitter_favorites** collection, find a **singular status** with a **tesla hashtag**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Room for in-class work\n",
    "doc = favs_coll.find_one({\"hashtags.text\": \"tesla\"},\n",
    "                         {'hashtags': 1, 'user.screen_name': 1, 'user.description': 1})\n",
    "print(doc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# find()\n",
    "Likewise pymongo's **find()** works exactly like mongo's console find() command. One thing to note `find({})` returns a cursor (iterable), not an actual document.\n",
    "\n",
    "**In Class Questions:**\n",
    " 1. What is the advantage to using a generator/iterable in this instance?\n",
    " 2. What is the benefit of being able to query for one document `find_one()` vs a list of documents `find()`?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "docs = favs_coll.find({})\n",
    "print(docs) # notice this is cursor, no actual data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(docs[600]) # By indexing we can extract results from the query"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Iterating Through Our Cursor\n",
    "We can prove the query executed correctly by iterating through all of the documents"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Our query\n",
    "docs = favs_coll.find({\"favorited_by_screen_name\": \"elonmusk\"})\n",
    "# Variable to store the state of the test\n",
    "worked = True\n",
    "\n",
    "# Iterate through each of the docs looking for an invalid state\n",
    "for doc in docs:\n",
    "    if doc['favorited_by_screen_name'] != 'elonmusk':\n",
    "        worked = False\n",
    "        break\n",
    "\n",
    "# If worked is still True, then our query worked (or at least passed this evaluation)\n",
    "if worked:\n",
    "    print(\"Worked!!\")\n",
    "else:\n",
    "    print(\"Failed!\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Instead of iterating through the documents, we can also extract all of the documents at once by calling `list(docs)`. This approach though comes with some drawbacks.\n",
    " - The code will have to wait for all of the records to be pulled (unless threaded)\n",
    " - You'll need to ensure that you have the memory to store all of the results\n",
    " - Any connection errors will reset the process\n",
    " - etc."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "docs = favs_coll.find({\"favorited_by_screen_name\": \"elonmusk\"})\n",
    "doc_lst = list(docs)\n",
    "print(len(doc_lst))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "docs.count()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## In Class Excercise:\n",
    "\n",
    "Using the **twitter_statuses** collection, calculate the **total number of favorites** that **elonmusk** has received"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "NameError",
     "evalue": "name 'db' is not defined",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-1-72006d50c552>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mstats_coll\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mdb\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mtwitter_statuses\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mNameError\u001b[0m: name 'db' is not defined"
     ]
    }
   ],
   "source": [
    "stats_coll = db.twitter_statuses"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Room for in-class work\n",
    "docs = stats_coll.find({'user.screen_name': 'elonmusk'})\n",
    "\n",
    "tot = sum([doc.get('favorite_count', 0) for doc in docs])\n",
    "\n",
    "print(tot)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Would we get the same result if we ran this processes against the **twitter_favorites** collection?"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Exception to the Rule\n",
    "While pymongo's pattern system effectively parallels the mongo shell, there is one key exception:\n",
    " - The use of the **$** \n",
    " \n",
    "In mongo shell the following is valid:\n",
    " - **`db.coll_name.find({\"attr\": {$exists: true}})`**\n",
    " \n",
    "However, in pymongo this would be phrased as:\n",
    " - **`db.coll_name.find({\"attr\": {\"$exists\": True}})`**\n",
    " \n",
    "Since **$** isn't a valid value in python, these functions need to be wrapped as strings."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## In Class Excercise:\n",
    "Using a mixture of mongo queries and python, determine if the person who has the most favorited tweet (***favorites collection***) in 2021 is a friend of Elon Musks (screen_name - 'elonmusk').\n",
    "\n",
    "Note: Sorting with pymongo is slightly different - `.sort([(\"field1\", 1), (\"field2\", -1)])`"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Space for work\n",
    "from datetime import datetime\n",
    "date = datetime(2021, 1, 1)\n",
    "docs = favs_coll.find({\"created_at\": {\"$gte\": date}}).sort([('favorite_count', -1)])\n",
    "user = docs[0].get('user').get('screen_name')\n",
    "\n",
    "friends_coll = db.twitter_friends\n",
    "doc = friends_coll.find_one({\n",
    "    \"$and\": [\n",
    "        {\"screen_name\": user},\n",
    "        {\"friend_of_screen_name\": 'elonmusk'}\n",
    "    ]\n",
    "})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "not friends\n"
     ]
    }
   ],
   "source": [
    "if doc:\n",
    "    print(\"friends\")\n",
    "else:\n",
    "    print(\"not friends\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# insert_one() and insert_many()\n",
    "These methods enable us to insert one or more documents into the collection\n",
    "\n",
    "**Do not run the following sections!**\n",
    "\n",
    "**Question**:\n",
    "Will the following cell cause an error?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "None\n"
     ]
    }
   ],
   "source": [
    "test_coll = db.test_collection\n",
    "doc = test_coll.find_one({\"test\": \"passed!\"})\n",
    "print(doc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can insert any valid object by simply calling:\n",
    " - **`coll_name.insert_one(doc)`**\n",
    " \n",
    "*Note: If we do not provide a `_id` field in the document mongo will automatically create one. This means that there is nothing stopping us from inserting duplicate records*"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "doc = {\"test\": \"passed!\"}\n",
    "result = test_coll.insert_one(doc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result.inserted_id"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can verify on the python side by querying for the record"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "doc = test_coll.find_one({\"test\": \"passed!\"})\n",
    "print(doc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also insert many documents at once:\n",
    " - **`coll_name.insert_many(docs)`**\n",
    "  - where docs is a list of valid BSON documents\n",
    "  \n",
    "  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#Don't run this - just for demonstration\n",
    "\n",
    "docs = [{'test': 'passed-' + str(x)} for x in range(5)]\n",
    "\n",
    "test_coll.insert_many(docs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Verification:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Since it's a sample collection it only has our inserted docs\n",
    "docs = test_coll.find({})\n",
    "\n",
    "docs_lst = list(docs)\n",
    "\n",
    "for doc in docs_lst:\n",
    "    # This will simply help the formatting on the output\n",
    "    print(doc)\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# update_one() and update_many()\n",
    "As discussed in the slides, these methods are used to modify an existing record.\n",
    "\n",
    "While they are a bit more complexed than the other methods, I did want to provide a little example.\n",
    "\n",
    "**`coll_name.update_one(find_pattern, update_pattern)`**\n",
    " 1. We find the documnet(s) that match the find_pattern\n",
    "  - The find_pattern follows the same structure as the mongo shell and pymongo find methods\n",
    " 2. We dictate the update pattern for the identified document(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Here we will be adding an attribute that indicates the document has been updated\n",
    "test_coll.update_one({\"test\": \"passed!\"}, {\"$set\": {\"updated\": True}})\n",
    "\n",
    "doc = test_coll.find_one({\"test\": \"updated\"})\n",
    "print(doc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Works the same way for **`coll_name.update_many(find_pattern, update_pattern)`**\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_coll.update_many({\"test\": {\"$exists\": True}}, {\"$set\": {\"updated\": True}})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "docs = test_coll.find({})\n",
    "for doc in docs:\n",
    "    # This will simply help the formatting on the output\n",
    "    print(doc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# delete_one() and delete_many()\n",
    "Deleting records works almost the same was as updating, except we only provide a **find_pattern** to the method.\n",
    "\n",
    "**`coll_name.delete_one(find_pattern)`**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "result = test_coll.delete_one({\"test\": \"updated\"})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we shouldn't be able to find that document:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "doc = test_coll.find_one({\"test\": \"updated\"})\n",
    "print(doc)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also inspect the **DeleteResult** from the command:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "print(result.raw_result)\n",
    "\n",
    "print(result.deleted_count)\n",
    "\n",
    "print(result.acknowledged)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Small example using **`coll_name.delete_many()`**"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def num_field(field):\n",
    "    docs = test_coll.find({field: {\"$exists\": True}})\n",
    "    count = sum(1 for x in docs)\n",
    "    return(count)   \n",
    "\n",
    "\n",
    "print(num_field('test'))\n",
    "test_coll.delete_many({'test': {\"$exists\": True}})\n",
    "print(num_field('test'))\n",
    "    "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## In Class Excercise:\n",
    " 1. Insert a JSON document into the test_collection with the following structure:\n",
    " ```JSON\n",
    "    {\n",
    "        \"name\": `your_name`,\n",
    "        \"favorite_movie\": `movie_name`,\n",
    "        \"favorite_bands\": [\n",
    "            `band_name_1`,\n",
    "            `band_name_2`,\n",
    "            `etc.`\n",
    "        ]\n",
    "    }\n",
    "```\n",
    " 2. Review the response object and execute a query in python to prove your document has sucessfully been inserted\n",
    " 3. Using python, delete your object and verify the results by reviewing the response object and querying the collection."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 35,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Space for work\n",
    "resp = test_coll.insert_one(\n",
    "    {\n",
    "        \"name\": \"Joel\",\n",
    "        \"favorite_movie\": 'Big Fish',\n",
    "        \"favorite_bands\": [\n",
    "            'Jon Bellion',\n",
    "            'Blink-182'\n",
    "        ]\n",
    "    }\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 36,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Inserted\n"
     ]
    }
   ],
   "source": [
    "if resp.acknowledged:\n",
    "    print(\"Inserted\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'_id': ObjectId('6019c687124fdc8e5d62b3ca'),\n",
       " 'name': 'Joel',\n",
       " 'favorite_movie': 'Big Fish',\n",
       " 'favorite_bands': ['Jon Bellion', 'Blink-182']}"
      ]
     },
     "execution_count": 37,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "_id = resp.inserted_id\n",
    "test_coll.find_one({\"_id\": _id})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [],
   "source": [
    "resp = test_coll.delete_one({\"_id\": _id})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "1 documents removed\n"
     ]
    }
   ],
   "source": [
    "if resp.acknowledged:\n",
    "    print(f'{resp.deleted_count} documents removed')"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [conda env:comparative_databases] *",
   "language": "python",
   "name": "conda-env-comparative_databases-py"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}