{"id":1587,"date":"2014-12-16T19:26:47","date_gmt":"2014-12-16T19:26:47","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=1587"},"modified":"2023-06-28T00:25:56","modified_gmt":"2023-06-28T07:25:56","slug":"creating-content-store-couchbase-learning-portal","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/ko\/creating-content-store-couchbase-learning-portal\/","title":{"rendered":"Couchbase - \ud559\uc2b5 \ud3ec\ud138\ub85c \ucf58\ud150\uce20 \uc2a4\ud1a0\uc5b4 \ub9cc\ub4e4\uae30"},"content":{"rendered":"<p>Two weeks ago McGraw Hill presented at CouchConf SF and our users expressed so much interest that I thought I&#8217;d share more details in a blog. Earlier this year McGraw Hill and Couchbase teamed up to build a proof-of-concept application showing off the power of using Couchbase and ElasticSearch together.<\/p>\n<p>The goal of the project was to build a self-adapting learning portal that delivers personalized results. Specifically that meant:<\/p>\n<ul>\n<li>Allow users to browse and search a variety of content (articles, images, and video)<\/li>\n<li>Fast access to both content and metadata<\/li>\n<li>Enhance user profiles based on user behaviors and actions<\/li>\n<li>Incorporate the user&#8217;s profile into search queries and deliver personalized results<\/li>\n<\/ul>\n<h3>Architecture<\/h3>\n<p>Couchbase Server was used to store all of the content meta-data, as well as the full-text source of the text articles. This gives the application sub-millisecond latency access to the primary data set.<\/p>\n<p>ElasticSearch was chosen to handle the full-text search requirements for the application. ElasticSearch combines rich querying capabilities with excellent clustering capabilities, making it a great match with Couchbase. Integration between Couchbase Server and ElasticSearch was provided by the\u00a0<a href=\"https:\/\/github.com\/couchbaselabs\/elasticsearch-transport-couchbase\" rel=\"nofollow\">Couchbase Transport plug-in<\/a>. This transport uses the Cross Data Center Replication feature of Couchbase Server 2.0 to reliably transfer all document mutations to the ElasticSearch index (<a href=\"https:\/\/www.couchbase.com\/blog\/couchbase-and-full-text-search-couchbase-transport-elasticsearch\/\" rel=\"nofollow\">Learn more about this here<\/a>).<\/p>\n<p>On the front-end, the decision was made to build the application using Ruby on Rails. Our primary objective in the code being to clearly document the best practices when using Couchbase and ElasticSearch together.<\/p>\n<h3>Learning Portal<\/h3>\n<p>Here is what a user sees when they first log in to the application.<\/p>\n<h5>Fast Access to Documents using Couchbase Client SDK<\/h5>\n<p>When a user selects on a particular piece of content, the data is loaded directly from Couchbase Server by its key. Here&#8217;s a sample document in Couchbase:<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;title&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;Vince Shields&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;url&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;https:\/\/en.wikipedia.org\/wiki\/Vince_Shields&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;type&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;text&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;is_text&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">1<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;is_video&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">0<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;is_image&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">0<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;popularity&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">0<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;views&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">0<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;categories&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">[<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;1900 births&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;1952 deaths&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;Baseball people from New Brunswick&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;Canadian baseball pitcher stubs&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;Fort Smith Twins players&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;Independence Producers players&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;Major League Baseball pitchers&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;Major League Baseball players from Canada&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;People from Fredericton&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;St. Louis Cardinals players&#8221;<\/span><br \/>\n<span style=\"color: #009900\">]<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;timestamp&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;2012-01-06T02:27:11Z&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;content&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;{{Infobox MLB player<span style=\"color: #000099;font-weight: bold\">n<\/span>|name=Vince Shields&#8230;&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;authors&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">[<\/span><br \/>\n<span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;name&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;Chris the speller&#8221;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #009900\">]<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;contributors&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">[<\/span><br \/>\n<span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;name&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;Chris the speller&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;timestamp&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;2012-01-06T02:27:11Z&#8221;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #009900\">]<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/div>\n<\/div>\n<p>&nbsp;<\/p>\n<h5>Top Contributors and Top Tags using Couchbase Map Reduce Views<\/h5>\n<p>Users of the system can browse content by exploring the systems top contributors and top tags.<\/p>\n<p>&nbsp;<\/p>\n<p>Let&#8217;s take a closer look at how the top tags are determined.<\/p>\n<p>First, here is the map function we&#8217;re using:<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #003366;font-weight: bold\">function<\/span><span style=\"color: #009900\">(<\/span>doc<span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #000066;font-weight: bold\">if<\/span> <span style=\"color: #009900\">(<\/span>doc.<span style=\"color: #660066\">type<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">{<\/span><br \/>\ndoc.<span style=\"color: #660066\">categories<\/span>.<span style=\"color: #660066\">forEach<\/span><span style=\"color: #009900\">(<\/span><span style=\"color: #003366;font-weight: bold\">function<\/span><span style=\"color: #009900\">(<\/span>category<span style=\"color: #009900\">)<\/span><span style=\"color: #009900\">{<\/span><br \/>\nemit<span style=\"color: #009900\">(<\/span>category<span style=\"color: #339933\">,<\/span> <span style=\"color: #003366;font-weight: bold\">null<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #009900\">)<\/span><span style=\"color: #339933\">;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/div>\n<\/div>\n<p>And we&#8217;re using the built-in reduce\u00a0<strong>_count<\/strong><\/p>\n<p>When we access this view with a group_level of 1, we see each tag, and the number of times it has been used to describe a document.<\/p>\n<p>&nbsp;<\/p>\n<p>Couchbase Views are sorted by the key, so we cannot directly query for the top 8 tags. Instead, we have a job that runs every 10 minutes, queries this view, sorts the results, and stores the top 8 results into another document in Couchbase. Here is what that document looks like:<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;tags&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">[<\/span><br \/>\n<span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;name&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;Living people&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;count&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">27554<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;name&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;Persondata templates without short description parameter&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;count&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">20971<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;name&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;All articles with unsourced statements&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;count&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">13509<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;name&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;Article Feedback Blacklist&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;count&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">9205<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;name&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;Articles with hCards&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;count&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">9028<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;name&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;Disambiguation pages&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;count&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">5912<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;name&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;Articles lacking sources from December 2009&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;count&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">4158<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;name&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;Commons category template with no category set&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;count&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">2904<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #009900\">]<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/div>\n<\/div>\n<p>Now, we have very fast access to the top-tags updated every 10 minutes.<\/p>\n<h5><\/h5>\n<h5>Full-Text Search<\/h5>\n<p>Users of the system can also perform complex search queries.<\/p>\n<p>&nbsp;<\/p>\n<p>Using this interface a user could search for the term &#8220;water&#8221;. This results in search query sent to ElasticSearch:<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;query&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;query_string&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;query&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;water&#8221;<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><\/div>\n<\/div>\n<p>This particular query matches 42 documents, below is a subset of the response showing 1 document:<\/p>\n<div class=\"geshifilter\">\n<div class=\"javascript geshifilter-javascript\" style=\"font-family: monospace\"><span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;took&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">5<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;timed_out&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #003366;font-weight: bold\">false<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;_shards&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;total&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">5<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;successful&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">5<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;failed&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">0<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;hits&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;total&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">42<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;max_score&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">1.0178552<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;hits&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">[<\/span><br \/>\n<span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;_index&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #3366cc\">&#8220;learning_portal&#8221;<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;_type&#8221;<\/span><span style=\"color: #339933\">:<\/span> couchbaseDocument<span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;_id&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">18087337<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;_score&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">1.0178552<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;_source&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;meta&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #009900\">{<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;id&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">18087337<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;rev&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">1<\/span><span style=\"color: #339933\">&#8211;<\/span>0017a16b2b29dc9c0000000000000000<span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;flags&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">0<\/span><span style=\"color: #339933\">,<\/span><br \/>\n<span style=\"color: #3366cc\">&#8220;expiration&#8221;<\/span><span style=\"color: #339933\">:<\/span> <span style=\"color: #cc0000\">0<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><br \/>\n<span style=\"color: #009900\">}<\/span><span style=\"color: #339933\">,<\/span>&#8230;<\/div>\n<\/div>\n<p>The important thing to note here is that the full document body is not included in the response from ElasticSearch. This was done by design, as we configured the index to not store the full source documents. The reason is simple, we already have fast access to the documents in Couchbase. Using the Couchbase Client SDK, we can perform a multi-get operation and efficiently pull down the document bodies. This allows us to render the search results screen:<\/p>\n<p>&nbsp;<\/p>\n<h3>More Information<\/h3>\n<ul>\n<li>Check out the presentation Chris Tse gave at\u00a0CouchConf<\/li>\n<li>All of the source code for the Learning Portal is available on\u00a0<a href=\"https:\/\/github.com\/couchbaselabs\/learningportal\/\" rel=\"nofollow\">github<\/a><\/li>\n<li>Want to learn more about the Couchbase ElasticSearch integration and have your questions answered? Sign up to\u00a0<a href=\"https:\/\/www.couchbase.com\/webinars\/\" rel=\"nofollow\">attend the webinar on October 24th<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Two weeks ago McGraw Hill presented at CouchConf SF and our users expressed so much interest that I thought I&#8217;d share more details in a blog. Earlier this year McGraw Hill and Couchbase teamed up to build a proof-of-concept application [&hellip;]<\/p>\n","protected":false},"author":16,"featured_media":13873,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"ppma_author":[9014],"class_list":["post-1587","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v27.3 (Yoast SEO v27.3) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>Creating a content store with Couchbase - The Learning Portal - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/ko\/creating-content-store-couchbase-learning-portal\/\" \/>\n<meta property=\"og:locale\" content=\"ko_KR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Creating a content store with Couchbase - The Learning Portal\" \/>\n<meta property=\"og:description\" content=\"Two weeks ago McGraw Hill presented at CouchConf SF and our users expressed so much interest that I thought I&#8217;d share more details in a blog. Earlier this year McGraw Hill and Couchbase teamed up to build a proof-of-concept application [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/ko\/creating-content-store-couchbase-learning-portal\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2014-12-16T19:26:47+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2023-06-28T07:25:56+00:00\" \/>\n<meta name=\"author\" content=\"Marty Schoch, Senior Software Engineer, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Marty Schoch, Senior Software Engineer, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"4\ubd84\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/\"},\"author\":{\"name\":\"Marty Schoch, Senior Software Engineer, Couchbase\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/8391bac860956a77004a3267314699b5\"},\"headline\":\"Creating a content store with Couchbase &#8211; The Learning Portal\",\"datePublished\":\"2014-12-16T19:26:47+00:00\",\"dateModified\":\"2023-06-28T07:25:56+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/\"},\"wordCount\":812,\"commentCount\":4,\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"articleSection\":[\"Uncategorized\"],\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/\",\"name\":\"Creating a content store with Couchbase - The Learning Portal - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"datePublished\":\"2014-12-16T19:26:47+00:00\",\"dateModified\":\"2023-06-28T07:25:56+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/#breadcrumb\"},\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/sites\\\/1\\\/2022\\\/11\\\/couchbase-nosql-dbaas.png\",\"width\":1800,\"height\":630},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/creating-content-store-couchbase-learning-portal\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Creating a content store with Couchbase &#8211; The Learning Portal\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ko-KR\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/wp-content\\\/uploads\\\/2023\\\/04\\\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/#\\\/schema\\\/person\\\/8391bac860956a77004a3267314699b5\",\"name\":\"Marty Schoch, Senior Software Engineer, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/2986697e6cd5f3ee6681e1e2af2f1097f0a0025e42b0327c9f09db42c2fc55b8?s=96&d=mm&r=ga82953547a154c93c3be4a865f6a0425\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/2986697e6cd5f3ee6681e1e2af2f1097f0a0025e42b0327c9f09db42c2fc55b8?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/2986697e6cd5f3ee6681e1e2af2f1097f0a0025e42b0327c9f09db42c2fc55b8?s=96&d=mm&r=g\",\"caption\":\"Marty Schoch, Senior Software Engineer, Couchbase\"},\"description\":\"Marty Schoch is a Senior Software Engineer at Couchbase. Marty is the author of the Couchbase Plugin for Elasticsearch and early versions of N1QL. Marty is also a core contributor to the Couchbase Go SDK and has worked on many experimental Couchbase Labs projects using Go. Currently, Marty is researching new index technology for future versions of Couchbase. He holds a bachelor's degree in computer science from the University of Maryland, College Park.\",\"url\":\"https:\\\/\\\/www.couchbase.com\\\/blog\\\/ko\\\/author\\\/marty-schoch\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4\ub85c \ucf58\ud150\uce20 \uc2a4\ud1a0\uc5b4 \ub9cc\ub4e4\uae30 - \ud559\uc2b5 \ud3ec\ud138 - \uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/ko\/creating-content-store-couchbase-learning-portal\/","og_locale":"ko_KR","og_type":"article","og_title":"Creating a content store with Couchbase - The Learning Portal","og_description":"Two weeks ago McGraw Hill presented at CouchConf SF and our users expressed so much interest that I thought I&#8217;d share more details in a blog. Earlier this year McGraw Hill and Couchbase teamed up to build a proof-of-concept application [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/ko\/creating-content-store-couchbase-learning-portal\/","og_site_name":"The Couchbase Blog","article_published_time":"2014-12-16T19:26:47+00:00","article_modified_time":"2023-06-28T07:25:56+00:00","author":"Marty Schoch, Senior Software Engineer, Couchbase","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Marty Schoch, Senior Software Engineer, Couchbase","Est. reading time":"4\ubd84"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/"},"author":{"name":"Marty Schoch, Senior Software Engineer, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/8391bac860956a77004a3267314699b5"},"headline":"Creating a content store with Couchbase &#8211; The Learning Portal","datePublished":"2014-12-16T19:26:47+00:00","dateModified":"2023-06-28T07:25:56+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/"},"wordCount":812,"commentCount":4,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","articleSection":["Uncategorized"],"inLanguage":"ko-KR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/","url":"https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/","name":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4\ub85c \ucf58\ud150\uce20 \uc2a4\ud1a0\uc5b4 \ub9cc\ub4e4\uae30 - \ud559\uc2b5 \ud3ec\ud138 - \uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","datePublished":"2014-12-16T19:26:47+00:00","dateModified":"2023-06-28T07:25:56+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/#breadcrumb"},"inLanguage":"ko-KR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/"]}]},{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2022\/11\/couchbase-nosql-dbaas.png","width":1800,"height":630},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/creating-content-store-couchbase-learning-portal\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Creating a content store with Couchbase &#8211; The Learning Portal"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","description":"NoSQL \ub370\uc774\ud130\ubca0\uc774\uc2a4, Couchbase","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ko-KR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/8391bac860956a77004a3267314699b5","name":"Marty Schoch, \uc218\uc11d \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc5d4\uc9c0\ub2c8\uc5b4, Couchbase","image":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/secure.gravatar.com\/avatar\/2986697e6cd5f3ee6681e1e2af2f1097f0a0025e42b0327c9f09db42c2fc55b8?s=96&d=mm&r=ga82953547a154c93c3be4a865f6a0425","url":"https:\/\/secure.gravatar.com\/avatar\/2986697e6cd5f3ee6681e1e2af2f1097f0a0025e42b0327c9f09db42c2fc55b8?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/2986697e6cd5f3ee6681e1e2af2f1097f0a0025e42b0327c9f09db42c2fc55b8?s=96&d=mm&r=g","caption":"Marty Schoch, Senior Software Engineer, Couchbase"},"description":"Marty Schoch\ub294 Couchbase\uc758 \uc120\uc784 \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc5d4\uc9c0\ub2c8\uc5b4\uc785\ub2c8\ub2e4. Marty\ub294 Elasticsearch\uc6a9 Couchbase \ud50c\ub7ec\uadf8\uc778\uacfc N1QL \ucd08\uae30 \ubc84\uc804\uc758 \uc800\uc790\uc785\ub2c8\ub2e4. \ub610\ud55c Couchbase Go SDK\uc758 \ud575\uc2ec \uae30\uc5ec\uc790\uc774\uae30\ub3c4 \ud558\uba70, Go\ub97c \uc0ac\uc6a9\ud574 \uc5ec\ub7ec \uc2e4\ud5d8\uc801\uc778 Couchbase Labs \ud504\ub85c\uc81d\ud2b8\uc5d0 \ucc38\uc5ec\ud588\uc2b5\ub2c8\ub2e4. \ud604\uc7ac Marty\ub294 Couchbase\uc758 \ud5a5\ud6c4 \ubc84\uc804\uc744 \uc704\ud55c \uc0c8\ub85c\uc6b4 \uc778\ub371\uc2a4 \uae30\uc220\uc744 \uc5f0\uad6c\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4. \uadf8\ub294 \uba54\ub9b4\ub79c\ub4dc \ub300\ud559\uad50 \uce7c\ub9ac\uc9c0 \ud30c\ud06c\uc5d0\uc11c \ucef4\ud4e8\ud130 \uacfc\ud559 \ud559\uc0ac \ud559\uc704\ub97c \ubc1b\uc558\uc2b5\ub2c8\ub2e4.","url":"https:\/\/www.couchbase.com\/blog\/ko\/author\/marty-schoch\/"}]}},"acf":[],"authors":[{"term_id":9014,"user_id":16,"is_guest":0,"slug":"marty-schoch","display_name":"Marty Schoch, Senior Software Engineer, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/2986697e6cd5f3ee6681e1e2af2f1097f0a0025e42b0327c9f09db42c2fc55b8?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts\/1587","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/users\/16"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/comments?post=1587"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts\/1587\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/media\/13873"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/media?parent=1587"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/categories?post=1587"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/tags?post=1587"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/ppma_author?post=1587"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}