{"id":5632,"date":"2012-12-16T15:05:08","date_gmt":"2012-12-16T13:05:08","guid":{"rendered":"http:\/\/www.javacodegeeks.com\/?p=5632"},"modified":"2012-12-16T15:01:26","modified_gmt":"2012-12-16T13:01:26","slug":"mapreduce-algorithms-order-inversion","status":"publish","type":"post","link":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html","title":{"rendered":"MapReduce Algorithms &#8211; Order Inversion"},"content":{"rendered":"<p>This post is another segment in the series presenting MapReduce algorithms as found in the <a href=\"http:\/\/www.amazon.com\/Data-Intensive-Processing-MapReduce-Synthesis-Technologies\/dp\/1608453421\" target=\"_blank\">Data-Intensive Text Processing with MapReduce<\/a> book. Previous installments are <a title=\"Working Through Data-Intensive Text Processing with MapReduce\" href=\"http:\/\/codingjunkie.net\/text-processing-with-mapreduce-part1\/\" target=\"_blank\">Local Aggregation<\/a>, <a title=\"Working Through Data-Intensive Text Processing with MapReduce \u2013 Local Aggregation Part II\" href=\"http:\/\/codingjunkie.net\/text-processing-with-mapreduce-part-2\/\" target=\"_blank\">Local Aggregation PartII<\/a> and <a title=\"Calculating A Co-Occurrence Matrix with Hadoop\" href=\"http:\/\/codingjunkie.net\/cooccurrence\/\" target=\"_blank\">Creating a Co-Occurrence Matrix<\/a>. This time we will discuss the order inversion pattern. The order inversion pattern exploits the sorting phase of MapReduce to push data needed for calculations to the reducer <em>ahead of<\/em> the data that will be manipulated.. Before you dismiss this as an edge condition for MapReduce, I urge you to read on as we will discuss how to use sorting to our advantage and cover using a custom partitioner, both of which are useful tools to have available.<ahref=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/12\/hadoop-logo.jpeg\"><img decoding=\"async\" class=\"alignright\" title=\"hadoop-logo\" src=\"http:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/12\/hadoop-logo.jpeg\" alt=\"\" width=\"300\" height=\"71\" \/><\/a><br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\n&nbsp;<br \/>\nAlthough many MapReduce programs are written at a higher level abstraction i.e Hive or Pig, it\u2019s still helpful to have an understanding of what\u2019s going on at a lower level.The order inversion pattern is found in chapter 3 of Data-Intensive Text Processing with MapReduce book. To illustrate the order inversion pattern we will be using the Pairs approach from the co-occurrence matrix pattern. When creating the co-occurrence matrix, we track the total counts of when words appear together. At a high level we take the Pairs approach and add a small twist, in addition to having the mapper emit a word pair such as (\u201cfoo\u201d,\u201dbar\u201d) we will emit an additional word pair of (\u201cfoo\u201d,\u201d*\u201d) and will do so for every word pair so we can easily achieve a total count for how often the left most word appears, and use that count to calculate our relative frequencies. This approach raised two specific problems. First we need to find a way to ensure word pairs (\u201cfoo\u201d,\u201d*\u201d) arrive at the reducer first. Secondly we need to make sure all word pairs with the same left word arrive at the same reducer. Before we solve those problems, let\u2019s take a look at our mapper code.<\/p>\n<h2>Mapper Code<\/h2>\n<p>First we need to modify our mapper from the Pairs approach. At the bottom of each loop after we have emitted all the word pairs for a particular word, we will emit the special token WordPair(\u201cword\u201d,\u201d*\u201d) along with the count of times the word on the left was found.<\/p>\n<pre class=\" brush:java\">public class PairsRelativeOccurrenceMapper extends Mapper&lt;LongWritable, Text, WordPair, IntWritable&gt; {\r\n    private WordPair wordPair = new WordPair();\r\n    private IntWritable ONE = new IntWritable(1);\r\n    private IntWritable totalCount = new IntWritable();\r\n\r\n    @Override\r\n    protected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {\r\n        int neighbors = context.getConfiguration().getInt('neighbors', 2);\r\n        String[] tokens = value.toString().split('\\\\s+');\r\n        if (tokens.length &gt; 1) {\r\n            for (int i = 0; i &lt; tokens.length; i++) {\r\n                    tokens[i] = tokens[i].replaceAll('\\\\W+','');\r\n\r\n                    if(tokens[i].equals('')){\r\n                        continue;\r\n                    }\r\n\r\n                    wordPair.setWord(tokens[i]);\r\n\r\n                    int start = (i - neighbors &lt; 0) ? 0 : i - neighbors;\r\n                    int end = (i + neighbors &gt;= tokens.length) ? tokens.length - 1 : i + neighbors;\r\n                    for (int j = start; j &lt;= end; j++) {\r\n                        if (j == i) continue;\r\n                        wordPair.setNeighbor(tokens[j].replaceAll('\\\\W',''));\r\n                        context.write(wordPair, ONE);\r\n                    }\r\n                    wordPair.setNeighbor('*');\r\n                    totalCount.set(end - start);\r\n                    context.write(wordPair, totalCount);\r\n            }\r\n        }\r\n    }\r\n}<\/pre>\n<p>Now that we\u2019ve generated a way to track the total numbers of times a particular word has been encountered, we need to make sure those special characters reach the reducer first so a total can be tallied to calculate the relative frequencies. We will have the sorting phase of the MapReduce process handle this for us by modifying the compareTo method on the WordPair object.<div style=\"display:inline-block; margin: 15px 0;\"> <div id=\"adngin-JavaCodeGeeks_incontent_video-0\" style=\"display:inline-block;\"><\/div> <\/div><\/p>\n<h2>Modified Sorting<\/h2>\n<p>We modify the compareTo method on the WordPair class so when a \u201c*\u201d caracter is encountered on the right that particular object is pushed to the top.<\/p>\n<pre class=\" brush:java\">    @Override\r\n    public int compareTo(WordPair other) {\r\n        int returnVal = this.word.compareTo(other.getWord());\r\n        if(returnVal != 0){\r\n            return returnVal;\r\n        }\r\n        if(this.neighbor.toString().equals('*')){\r\n            return -1;\r\n        }else if(other.getNeighbor().toString().equals('*')){\r\n            return 1;\r\n        }\r\n        return this.neighbor.compareTo(other.getNeighbor());\r\n    }<\/pre>\n<p>By modifying the compareTo method we now are guaranteed that any WordPair with the special character will be sorted to the top and arrive at the reducer first. This leads to our second specialization, how can we guarantee that all WordPair objects with a given left word will be sent to the same reducer? The answer is to create a custom partitioner.<\/p>\n<h2>Custom Partitioner<\/h2>\n<p>Intermediate keys are shuffled to reducers by calculating the hashcode of the key modulo the number of reducers. But our WordPair objects contain two words, so taking the hashcode of the entire object clearly won\u2019t work. We need to wright a custom Partitioner that only takes into consideration the left word when it comes to determining which reducer to send the output to.<\/p>\n<pre class=\" brush:java\">public class WordPairPartitioner extends Partitioner&lt;WordPair,IntWritable&gt; {\r\n\r\n    @Override\r\n    public int getPartition(WordPair wordPair, IntWritable intWritable, int numPartitions) {\r\n        return wordPair.getWord().hashCode() % numPartitions;\r\n    }\r\n}<\/pre>\n<p>Now we are guaranteed that all of the WordPair objects with the same left word are sent to the same reducer. All that is left is to construct a reducer to take advantage of the format of the data being sent.<\/p>\n<h2>Reducer<\/h2>\n<p>Building the reducer for the inverted order inversion pattern is straight forward. It will involve keeping a counter variable and a \u201ccurrent\u201d word variable. The reducer will check the input key WordPair for the special character \u201c*\u201d on the right. If the word on the left is not equal to the \u201ccurrent\u201d word we will re-set the counter and sum all of the values to obtain a total number of times the given current word was observed. We will now process the next WordPair objects, sum the counts and divide by our counter variable to obtain a relative frequency. This process will continue until another special character is encountered and the process starts over.<\/p>\n<pre class=\" brush:java\">public class PairsRelativeOccurrenceReducer extends Reducer&lt;WordPair, IntWritable, WordPair, DoubleWritable&gt; {\r\n    private DoubleWritable totalCount = new DoubleWritable();\r\n    private DoubleWritable relativeCount = new DoubleWritable();\r\n    private Text currentWord = new Text('NOT_SET');\r\n    private Text flag = new Text('*');\r\n\r\n    @Override\r\n    protected void reduce(WordPair key, Iterable&lt;IntWritable&gt; values, Context context) throws IOException, InterruptedException {\r\n        if (key.getNeighbor().equals(flag)) {\r\n            if (key.getWord().equals(currentWord)) {\r\n                totalCount.set(totalCount.get() + getTotalCount(values));\r\n            } else {\r\n                currentWord.set(key.getWord());\r\n                totalCount.set(0);\r\n                totalCount.set(getTotalCount(values));\r\n            }\r\n        } else {\r\n            int count = getTotalCount(values);\r\n            relativeCount.set((double) count \/ totalCount.get());\r\n            context.write(key, relativeCount);\r\n        }\r\n    }\r\n  private int getTotalCount(Iterable&lt;IntWritable&gt; values) {\r\n        int count = 0;\r\n        for (IntWritable value : values) {\r\n            count += value.get();\r\n        }\r\n        return count;\r\n    }\r\n}<\/pre>\n<p>By manipulating the sort order and creating a custom partitioner, we have been able to send data to a reducer needed for a calculation, before the data needed for those calculation arrive. Although not shown here, a combiner was used to run the MapReduce job. This approach is also a good candidate for the \u201cin-mapper\u201d combining pattern.<\/p>\n<h2>Example &amp; Results<\/h2>\n<p>Given that the holidays are upon us, I felt it was timely to run an example of the order inversion pattern against the novel \u201cA Christmas Carol\u201d by Charles Dickens. I know it\u2019s corny, but it serves the purpose.<\/p>\n<pre class=\" brush:java\">new-host-2:sbin bbejeck$ hdfs dfs -cat relative\/part* | grep Humbug\r\n{word=[Humbug] neighbor=[Scrooge]}\t0.2222222222222222\r\n{word=[Humbug] neighbor=[creation]}\t0.1111111111111111\r\n{word=[Humbug] neighbor=[own]}\t0.1111111111111111\r\n{word=[Humbug] neighbor=[said]}\t0.2222222222222222\r\n{word=[Humbug] neighbor=[say]}\t0.1111111111111111\r\n{word=[Humbug] neighbor=[to]}\t0.1111111111111111\r\n{word=[Humbug] neighbor=[with]}\t0.1111111111111111\r\n{word=[Scrooge] neighbor=[Humbug]}\t0.0020833333333333333\r\n{word=[creation] neighbor=[Humbug]}\t0.1\r\n{word=[own] neighbor=[Humbug]}\t0.006097560975609756\r\n{word=[said] neighbor=[Humbug]}\t0.0026246719160104987\r\n{word=[say] neighbor=[Humbug]}\t0.010526315789473684\r\n{word=[to] neighbor=[Humbug]}\t3.97456279809221E-4\r\n{word=[with] neighbor=[Humbug]}\t9.372071227741331E-4<\/pre>\n<h2>Conclusion<\/h2>\n<p>While calculating relative word occurrence frequencies probably is not a common task, we have been able to demonstrate useful examples of sorting and using a custom partitioner, which are good tools to have at your disposal when building MapReduce programs. As stated before, even if most of your MapReduce is written at higher level of abstraction like Hive or Pig, it\u2019s still instructive to have an understanding of what is going on under the hood. Thanks for your time.<br \/>\n&nbsp;<\/p>\n<p><strong><em>Reference: <\/em><\/strong><a href=\"http:\/\/codingjunkie.net\/order-inversion\/\">MapReduce Algorithms \u2013 Order Inversion<\/a> from our <a href=\"http:\/\/www.javacodegeeks.com\/p\/jcg.html\">JCG partner<\/a> Bill Bejeck at the <a href=\"http:\/\/codingjunkie.net\/\">Random Thoughts On Coding<\/a> blog.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This post is another segment in the series presenting MapReduce algorithms as found in the Data-Intensive Text Processing with MapReduce book. Previous installments are Local Aggregation, Local Aggregation PartII and Creating a Co-Occurrence Matrix. This time we will discuss the order inversion pattern. The order inversion pattern exploits the sorting phase of MapReduce to push &hellip;<\/p>\n","protected":false},"author":110,"featured_media":62,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[8],"tags":[184,183],"class_list":["post-5632","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-enterprise-java","tag-apache-hadoop","tag-mapreduce"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>MapReduce Algorithms - Order Inversion<\/title>\n<meta name=\"description\" content=\"This post is another segment in the series presenting MapReduce algorithms as found in the Data-Intensive Text Processing with MapReduce book. Previous\" \/>\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.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"MapReduce Algorithms - Order Inversion\" \/>\n<meta property=\"og:description\" content=\"This post is another segment in the series presenting MapReduce algorithms as found in the Data-Intensive Text Processing with MapReduce book. Previous\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html\" \/>\n<meta property=\"og:site_name\" content=\"Java Code Geeks\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/javacodegeeks\" \/>\n<meta property=\"article:published_time\" content=\"2012-12-16T13:05:08+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-hadoop-logo.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"150\" \/>\n\t<meta property=\"og:image:height\" content=\"150\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Bill Bejeck\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:site\" content=\"@javacodegeeks\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Bill Bejeck\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html\"},\"author\":{\"name\":\"Bill Bejeck\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/69f9f11896bf9cfd7278b440efeda646\"},\"headline\":\"MapReduce Algorithms &#8211; Order Inversion\",\"datePublished\":\"2012-12-16T13:05:08+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html\"},\"wordCount\":956,\"commentCount\":2,\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-hadoop-logo.jpg\",\"keywords\":[\"Apache Hadoop\",\"MapReduce\"],\"articleSection\":[\"Enterprise Java\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html\",\"name\":\"MapReduce Algorithms - Order Inversion\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-hadoop-logo.jpg\",\"datePublished\":\"2012-12-16T13:05:08+00:00\",\"description\":\"This post is another segment in the series presenting MapReduce algorithms as found in the Data-Intensive Text Processing with MapReduce book. Previous\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html#primaryimage\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-hadoop-logo.jpg\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2012\\\/10\\\/apache-hadoop-logo.jpg\",\"width\":150,\"height\":150},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/2012\\\/12\\\/mapreduce-algorithms-order-inversion.html#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Enterprise Java\",\"item\":\"https:\\\/\\\/www.javacodegeeks.com\\\/category\\\/java\\\/enterprise-java\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"MapReduce Algorithms &#8211; Order Inversion\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#website\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"name\":\"Java Code Geeks\",\"description\":\"Java Developers Resource Center\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\"},\"alternateName\":\"JCG\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.javacodegeeks.com\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#organization\",\"name\":\"Exelixis Media P.C.\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"contentUrl\":\"https:\\\/\\\/www.javacodegeeks.com\\\/wp-content\\\/uploads\\\/2022\\\/06\\\/exelixis-logo.png\",\"width\":864,\"height\":246,\"caption\":\"Exelixis Media P.C.\"},\"image\":{\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/www.facebook.com\\\/javacodegeeks\",\"https:\\\/\\\/x.com\\\/javacodegeeks\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.javacodegeeks.com\\\/#\\\/schema\\\/person\\\/69f9f11896bf9cfd7278b440efeda646\",\"name\":\"Bill Bejeck\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0ab8cd639470515ff498599471cc60f21b2d0b14301ff22cadc708dc19c8be?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0ab8cd639470515ff498599471cc60f21b2d0b14301ff22cadc708dc19c8be?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/6f0ab8cd639470515ff498599471cc60f21b2d0b14301ff22cadc708dc19c8be?s=96&d=mm&r=g\",\"caption\":\"Bill Bejeck\"},\"description\":\"Husband, father of 3, passionate about software development.\",\"sameAs\":[\"http:\\\/\\\/codingjunkie.net\\\/\"],\"url\":\"https:\\\/\\\/www.javacodegeeks.com\\\/author\\\/Bill-Bejeck\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"MapReduce Algorithms - Order Inversion","description":"This post is another segment in the series presenting MapReduce algorithms as found in the Data-Intensive Text Processing with MapReduce book. Previous","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.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html","og_locale":"en_US","og_type":"article","og_title":"MapReduce Algorithms - Order Inversion","og_description":"This post is another segment in the series presenting MapReduce algorithms as found in the Data-Intensive Text Processing with MapReduce book. Previous","og_url":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html","og_site_name":"Java Code Geeks","article_publisher":"https:\/\/www.facebook.com\/javacodegeeks","article_published_time":"2012-12-16T13:05:08+00:00","og_image":[{"width":150,"height":150,"url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-hadoop-logo.jpg","type":"image\/jpeg"}],"author":"Bill Bejeck","twitter_card":"summary_large_image","twitter_creator":"@javacodegeeks","twitter_site":"@javacodegeeks","twitter_misc":{"Written by":"Bill Bejeck","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html#article","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html"},"author":{"name":"Bill Bejeck","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/69f9f11896bf9cfd7278b440efeda646"},"headline":"MapReduce Algorithms &#8211; Order Inversion","datePublished":"2012-12-16T13:05:08+00:00","mainEntityOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html"},"wordCount":956,"commentCount":2,"publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-hadoop-logo.jpg","keywords":["Apache Hadoop","MapReduce"],"articleSection":["Enterprise Java"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html","url":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html","name":"MapReduce Algorithms - Order Inversion","isPartOf":{"@id":"https:\/\/www.javacodegeeks.com\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html#primaryimage"},"image":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html#primaryimage"},"thumbnailUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-hadoop-logo.jpg","datePublished":"2012-12-16T13:05:08+00:00","description":"This post is another segment in the series presenting MapReduce algorithms as found in the Data-Intensive Text Processing with MapReduce book. Previous","breadcrumb":{"@id":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html#primaryimage","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-hadoop-logo.jpg","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2012\/10\/apache-hadoop-logo.jpg","width":150,"height":150},{"@type":"BreadcrumbList","@id":"https:\/\/www.javacodegeeks.com\/2012\/12\/mapreduce-algorithms-order-inversion.html#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.javacodegeeks.com\/"},{"@type":"ListItem","position":2,"name":"Java","item":"https:\/\/www.javacodegeeks.com\/category\/java"},{"@type":"ListItem","position":3,"name":"Enterprise Java","item":"https:\/\/www.javacodegeeks.com\/category\/java\/enterprise-java"},{"@type":"ListItem","position":4,"name":"MapReduce Algorithms &#8211; Order Inversion"}]},{"@type":"WebSite","@id":"https:\/\/www.javacodegeeks.com\/#website","url":"https:\/\/www.javacodegeeks.com\/","name":"Java Code Geeks","description":"Java Developers Resource Center","publisher":{"@id":"https:\/\/www.javacodegeeks.com\/#organization"},"alternateName":"JCG","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.javacodegeeks.com\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/www.javacodegeeks.com\/#organization","name":"Exelixis Media P.C.","url":"https:\/\/www.javacodegeeks.com\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/","url":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","contentUrl":"https:\/\/www.javacodegeeks.com\/wp-content\/uploads\/2022\/06\/exelixis-logo.png","width":864,"height":246,"caption":"Exelixis Media P.C."},"image":{"@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/www.facebook.com\/javacodegeeks","https:\/\/x.com\/javacodegeeks"]},{"@type":"Person","@id":"https:\/\/www.javacodegeeks.com\/#\/schema\/person\/69f9f11896bf9cfd7278b440efeda646","name":"Bill Bejeck","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/6f0ab8cd639470515ff498599471cc60f21b2d0b14301ff22cadc708dc19c8be?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/6f0ab8cd639470515ff498599471cc60f21b2d0b14301ff22cadc708dc19c8be?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/6f0ab8cd639470515ff498599471cc60f21b2d0b14301ff22cadc708dc19c8be?s=96&d=mm&r=g","caption":"Bill Bejeck"},"description":"Husband, father of 3, passionate about software development.","sameAs":["http:\/\/codingjunkie.net\/"],"url":"https:\/\/www.javacodegeeks.com\/author\/Bill-Bejeck"}]}},"_links":{"self":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/5632","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/users\/110"}],"replies":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/comments?post=5632"}],"version-history":[{"count":0,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/posts\/5632\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media\/62"}],"wp:attachment":[{"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/media?parent=5632"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/categories?post=5632"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.javacodegeeks.com\/wp-json\/wp\/v2\/tags?post=5632"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}