{"id":2448,"date":"2015-07-13T02:53:15","date_gmt":"2015-07-13T02:53:15","guid":{"rendered":"http:\/\/www.garysieling.com\/blog\/?p=2448"},"modified":"2015-07-13T02:53:15","modified_gmt":"2015-07-13T02:53:15","slug":"rethinkdb-compute-levenshtein-edit-distance-in-python","status":"publish","type":"post","link":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/","title":{"rendered":"RethinkDB: Compute Levenshtein Edit Distance in python"},"content":{"rendered":"<p>RethinkDB does not have a built-in distance metric like Levenshtein edit distance, but it is fairly easy to update rows in place. I found some examples of people attempting to build regular expressions to match specific Levenshtein edit distances, but this does not seem like a high performance approach, especially for finding things more than one character apart.<\/p>\n<p>To start, you must first install the Levenstein library for Python:<\/p>\n<pre lang=\"bash\">\npip install python-levenshtein\n<\/pre>\n<p>Having done that, you can load your database:<\/p>\n<pre lang=\"python\">\nimport Levenshtein\n\nimport rethinkdb as r\nr.connect(\"localhost\", 28015).repl()\n\ndb = r.db(\"search\")\ntable = db.table(\"industries\")\n<\/pre>\n<p>Once you have the table, it&#8217;s relatively easy to get a single test row, modify it, and upload it to the database. Remember to add .run() to the end of the query. Once you do this, you can filter to rows that contain the column you&#8217;re interested in (in this case, you should get one row back from the last query). The reason that you can update a document you downloaded previously is that RethinkDB automatically pulls down the document&#8217;s ID.<\/p>\n<pre lang=\"python\">\ndoc = [x for x in table.limit(1).run()]\n\ndoc['Title_Query_Distance'] = \\\n  Levenshtein.ratio(doc['search_query'], doc['Title'])\ndoc['Title_Description_Distance'] = \\\n  Levenshtein.ratio(doc['search_query'], doc['Description'])\n\ntable.update(doc).run()\n\n[x for x in table.filter('Title_Query_Distance').run()]\n<\/pre>\n<p>Having done all this, you can run this query for each record in the database (if you&#8217;re splitting the work up, you may wish to do this only on rows with the value not populated):<\/p>\n<pre lang=\"python\">\ndef updateDoc(table, doc):\n  doc['Title_Query_Distance'] = \\\n    Levenshtein.ratio(doc['search_query'], doc['Title'])\n  doc['Title_Description_Distance'] = \\\n    Levenshtein.ratio(doc['search_query'], doc['Description'])\n  table.update(doc).run()\n\n# this query takes about ten seconds on a 31k row table, with no indexes\ntoUpdate = \\\n  [doc for doc in \\\n    table.filter(r.row.has_fields(\"Title_Query_Distance\").not_()).run()]\n\n# this query can take hours (30k row table)\n[updateDoc(table, doc) for doc in toUpdate]\n<\/pre>\n<p>Once we&#8217;ve done this, it&#8217;s a good practice to do some diagnostic queries, to verify everything updated as expected (these two should return matching counts)<\/p>\n<pre lang=\"python\">\ntable.filter(lambda x: x['Title_Query_Distance']).count().run()\ntable.count().run()\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>RethinkDB does not have a built-in distance metric like Levenshtein edit distance, but it is fairly easy to update rows in place. I found some examples of people attempting to build regular expressions to match specific Levenshtein edit distances, but this does not seem like a high performance approach, especially for finding things more than &hellip; <\/p>\n<p class=\"link-more\"><a href=\"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;RethinkDB: Compute Levenshtein Edit Distance in python&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"_monsterinsights_skip_tracking":false,"footnotes":""},"categories":[4],"tags":[157,160,447,462,466],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.9 - aioseo.com -->\n\t<meta name=\"description\" content=\"RethinkDB does not have a built-in distance metric like Levenshtein edit distance, but it is fairly easy to update rows in place. I found some examples of people attempting to build regular expressions to match specific Levenshtein edit distances, but this does not seem like a high performance approach, especially for finding things more than\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"gary\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.9\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Gary Sieling - Software Engineer\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"RethinkDB: Compute Levenshtein Edit Distance in python - Gary Sieling\" \/>\n\t\t<meta property=\"og:description\" content=\"RethinkDB does not have a built-in distance metric like Levenshtein edit distance, but it is fairly easy to update rows in place. I found some examples of people attempting to build regular expressions to match specific Levenshtein edit distances, but this does not seem like a high performance approach, especially for finding things more than\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2015-07-13T02:53:15+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2015-07-13T02:53:15+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n\t\t<meta name=\"twitter:title\" content=\"RethinkDB: Compute Levenshtein Edit Distance in python - Gary Sieling\" \/>\n\t\t<meta name=\"twitter:description\" content=\"RethinkDB does not have a built-in distance metric like Levenshtein edit distance, but it is fairly easy to update rows in place. I found some examples of people attempting to build regular expressions to match specific Levenshtein edit distances, but this does not seem like a high performance approach, especially for finding things more than\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"BlogPosting\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-compute-levenshtein-edit-distance-in-python\\\/#blogposting\",\"name\":\"RethinkDB: Compute Levenshtein Edit Distance in python - Gary Sieling\",\"headline\":\"RethinkDB: Compute Levenshtein Edit Distance in python\",\"author\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/#organization\"},\"datePublished\":\"2015-07-13T02:53:15+00:00\",\"dateModified\":\"2015-07-13T02:53:15+00:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-compute-levenshtein-edit-distance-in-python\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-compute-levenshtein-edit-distance-in-python\\\/#webpage\"},\"articleSection\":\"Code Examples, database, databases, python, reql, rethinkdb\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-compute-levenshtein-edit-distance-in-python\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.garysieling.com\\\/blog\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/category\\\/code-examples\\\/#listItem\",\"name\":\"Code Examples\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/category\\\/code-examples\\\/#listItem\",\"position\":2,\"name\":\"Code Examples\",\"item\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/category\\\/code-examples\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-compute-levenshtein-edit-distance-in-python\\\/#listItem\",\"name\":\"RethinkDB: Compute Levenshtein Edit Distance in python\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-compute-levenshtein-edit-distance-in-python\\\/#listItem\",\"position\":3,\"name\":\"RethinkDB: Compute Levenshtein Edit Distance in python\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/category\\\/code-examples\\\/#listItem\",\"name\":\"Code Examples\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/#organization\",\"name\":\"Gary Sieling\",\"description\":\"Software Engineer\",\"url\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/#author\",\"url\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/\",\"name\":\"gary\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-compute-levenshtein-edit-distance-in-python\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/0be925276d848ffe98a6a9dc8cf33e67?s=96&d=identicon&r=g\",\"width\":96,\"height\":96,\"caption\":\"gary\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-compute-levenshtein-edit-distance-in-python\\\/#webpage\",\"url\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-compute-levenshtein-edit-distance-in-python\\\/\",\"name\":\"RethinkDB: Compute Levenshtein Edit Distance in python - Gary Sieling\",\"description\":\"RethinkDB does not have a built-in distance metric like Levenshtein edit distance, but it is fairly easy to update rows in place. I found some examples of people attempting to build regular expressions to match specific Levenshtein edit distances, but this does not seem like a high performance approach, especially for finding things more than\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/rethinkdb-compute-levenshtein-edit-distance-in-python\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/author\\\/gary\\\/#author\"},\"datePublished\":\"2015-07-13T02:53:15+00:00\",\"dateModified\":\"2015-07-13T02:53:15+00:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/\",\"name\":\"Gary Sieling\",\"description\":\"Software Engineer\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.garysieling.com\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"RethinkDB: Compute Levenshtein Edit Distance in python - Gary Sieling","description":"RethinkDB does not have a built-in distance metric like Levenshtein edit distance, but it is fairly easy to update rows in place. I found some examples of people attempting to build regular expressions to match specific Levenshtein edit distances, but this does not seem like a high performance approach, especially for finding things more than","canonical_url":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"BlogPosting","@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/#blogposting","name":"RethinkDB: Compute Levenshtein Edit Distance in python - Gary Sieling","headline":"RethinkDB: Compute Levenshtein Edit Distance in python","author":{"@id":"https:\/\/www.garysieling.com\/blog\/author\/gary\/#author"},"publisher":{"@id":"https:\/\/www.garysieling.com\/blog\/#organization"},"datePublished":"2015-07-13T02:53:15+00:00","dateModified":"2015-07-13T02:53:15+00:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/#webpage"},"isPartOf":{"@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/#webpage"},"articleSection":"Code Examples, database, databases, python, reql, rethinkdb"},{"@type":"BreadcrumbList","@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog#listItem","position":1,"name":"Home","item":"https:\/\/www.garysieling.com\/blog","nextItem":{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog\/category\/code-examples\/#listItem","name":"Code Examples"}},{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog\/category\/code-examples\/#listItem","position":2,"name":"Code Examples","item":"https:\/\/www.garysieling.com\/blog\/category\/code-examples\/","nextItem":{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/#listItem","name":"RethinkDB: Compute Levenshtein Edit Distance in python"},"previousItem":{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/#listItem","position":3,"name":"RethinkDB: Compute Levenshtein Edit Distance in python","previousItem":{"@type":"ListItem","@id":"https:\/\/www.garysieling.com\/blog\/category\/code-examples\/#listItem","name":"Code Examples"}}]},{"@type":"Organization","@id":"https:\/\/www.garysieling.com\/blog\/#organization","name":"Gary Sieling","description":"Software Engineer","url":"https:\/\/www.garysieling.com\/blog\/"},{"@type":"Person","@id":"https:\/\/www.garysieling.com\/blog\/author\/gary\/#author","url":"https:\/\/www.garysieling.com\/blog\/author\/gary\/","name":"gary","image":{"@type":"ImageObject","@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/0be925276d848ffe98a6a9dc8cf33e67?s=96&d=identicon&r=g","width":96,"height":96,"caption":"gary"}},{"@type":"WebPage","@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/#webpage","url":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/","name":"RethinkDB: Compute Levenshtein Edit Distance in python - Gary Sieling","description":"RethinkDB does not have a built-in distance metric like Levenshtein edit distance, but it is fairly easy to update rows in place. I found some examples of people attempting to build regular expressions to match specific Levenshtein edit distances, but this does not seem like a high performance approach, especially for finding things more than","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/www.garysieling.com\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/#breadcrumblist"},"author":{"@id":"https:\/\/www.garysieling.com\/blog\/author\/gary\/#author"},"creator":{"@id":"https:\/\/www.garysieling.com\/blog\/author\/gary\/#author"},"datePublished":"2015-07-13T02:53:15+00:00","dateModified":"2015-07-13T02:53:15+00:00"},{"@type":"WebSite","@id":"https:\/\/www.garysieling.com\/blog\/#website","url":"https:\/\/www.garysieling.com\/blog\/","name":"Gary Sieling","description":"Software Engineer","inLanguage":"en-US","publisher":{"@id":"https:\/\/www.garysieling.com\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Gary Sieling - Software Engineer","og:type":"article","og:title":"RethinkDB: Compute Levenshtein Edit Distance in python - Gary Sieling","og:description":"RethinkDB does not have a built-in distance metric like Levenshtein edit distance, but it is fairly easy to update rows in place. I found some examples of people attempting to build regular expressions to match specific Levenshtein edit distances, but this does not seem like a high performance approach, especially for finding things more than","og:url":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/","article:published_time":"2015-07-13T02:53:15+00:00","article:modified_time":"2015-07-13T02:53:15+00:00","twitter:card":"summary_large_image","twitter:title":"RethinkDB: Compute Levenshtein Edit Distance in python - Gary Sieling","twitter:description":"RethinkDB does not have a built-in distance metric like Levenshtein edit distance, but it is fairly easy to update rows in place. I found some examples of people attempting to build regular expressions to match specific Levenshtein edit distances, but this does not seem like a high performance approach, especially for finding things more than"},"aioseo_meta_data":{"post_id":"2448","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":"default","schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"limit_modified_date":false,"created":"2023-02-04 16:27:34","updated":"2026-07-06 01:12:49","ai":null,"breadcrumb_settings":null,"seo_analyzer_scan_date":null},"aioseo_breadcrumb":"<div class=\"aioseo-breadcrumbs\"><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.garysieling.com\/blog\" title=\"Home\">Home<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\t<a href=\"https:\/\/www.garysieling.com\/blog\/category\/code-examples\/\" title=\"Code Examples\">Code Examples<\/a>\n\t\t<\/span><span class=\"aioseo-breadcrumb-separator\">&raquo;<\/span><span class=\"aioseo-breadcrumb\">\n\t\t\tRethinkDB: Compute Levenshtein Edit Distance in python\n\t\t<\/span><\/div>","aioseo_breadcrumb_json":[{"label":"Home","link":"https:\/\/www.garysieling.com\/blog"},{"label":"Code Examples","link":"https:\/\/www.garysieling.com\/blog\/category\/code-examples\/"},{"label":"RethinkDB: Compute Levenshtein Edit Distance in python","link":"https:\/\/www.garysieling.com\/blog\/rethinkdb-compute-levenshtein-edit-distance-in-python\/"}],"amp_enabled":true,"_links":{"self":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts\/2448"}],"collection":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/comments?post=2448"}],"version-history":[{"count":0,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/posts\/2448\/revisions"}],"wp:attachment":[{"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/media?parent=2448"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/categories?post=2448"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.garysieling.com\/blog\/wp-json\/wp\/v2\/tags?post=2448"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}