<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Jordan Soo Yen Yih</title>
    <description>The latest articles on DEV Community by Jordan Soo Yen Yih (@yenyih).</description>
    <link>https://dev.to/yenyih</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F254553%2F5c16447a-c80b-4eed-b468-444adb112bca.jpg</url>
      <title>DEV Community: Jordan Soo Yen Yih</title>
      <link>https://dev.to/yenyih</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yenyih"/>
    <language>en</language>
    <item>
      <title>Bun - The fastest Javascript Runtime</title>
      <dc:creator>Jordan Soo Yen Yih</dc:creator>
      <pubDate>Thu, 07 Jul 2022 11:01:54 +0000</pubDate>
      <link>https://dev.to/yenyih/bun-the-fastest-javascript-runtime-3nl3</link>
      <guid>https://dev.to/yenyih/bun-the-fastest-javascript-runtime-3nl3</guid>
      <description>&lt;p&gt;&lt;a href="https://bun.sh/" rel="noopener noreferrer"&gt;Bun&lt;/a&gt; - the new Javascript runtime has just announced its first beta release and makes the claimed that it's significantly faster than Node and Deno, not just a little bit faster, but orders of magnitude faster. What makes Bun special?&lt;/p&gt;

&lt;h2&gt;
  
  
  Performance ⚡
&lt;/h2&gt;

&lt;p&gt;It doesn't use the V8 engine but instead uses the JavaScriptCore from WebKit which is generally considered to be faster. In addition it's written in a low level programming language called &lt;a href="https://ziglang.org/" rel="noopener noreferrer"&gt;ZIG&lt;/a&gt; that similar to C or Rust and the creator of Bun say ZIG the lack of hidden control flow makes it much simpler to write fast software.&lt;/p&gt;

&lt;h2&gt;
  
  
  All-IN-ONE Runtime 🎁
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Native module bundler to replace tools like Webpack.&lt;/li&gt;
&lt;li&gt;Native transpiler to support Typescript code out of the box.&lt;/li&gt;
&lt;li&gt;Top level await (just like Deno🦖)&lt;/li&gt;
&lt;li&gt;Auto transpile JSX files&lt;/li&gt;
&lt;li&gt;Supports WebAPI like &lt;code&gt;fetch&lt;/code&gt;, &lt;code&gt;WebSocket&lt;/code&gt; and &lt;code&gt;ReadableStream&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Supports many Node core modules as well as Node API which will allow many NPM packages also work in Bun.&lt;/li&gt;
&lt;li&gt;Implements Node.js' module resolution algorithm, means you can install packages from npm into bun and those packages install 20x faster.⚡😲&lt;/li&gt;
&lt;li&gt;Environment variables load automatically, no more &lt;code&gt;dotenv&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Native test runner like Jest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try it out, if you are using Windows, you are required to use WSL to install Bun.&lt;/p&gt;

&lt;p&gt;Thank you for reading.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>node</category>
      <category>deno</category>
    </item>
    <item>
      <title>Temporal instead of Date</title>
      <dc:creator>Jordan Soo Yen Yih</dc:creator>
      <pubDate>Sat, 02 Apr 2022 09:35:09 +0000</pubDate>
      <link>https://dev.to/yenyih/temporal-instead-of-date-3e0d</link>
      <guid>https://dev.to/yenyih/temporal-instead-of-date-3e0d</guid>
      <description>&lt;p&gt;JavaScript Date is fundamentally specified as the number of milliseconds that have elapsed since the &lt;a href="https://tc39.es/ecma262/multipage/numbers-and-dates.html#sec-time-values-and-time-range" rel="noopener noreferrer"&gt;ECMAScript epoch&lt;/a&gt;, which is defined as January 1, 1970, UTC. However, there are some problems with the current JavaScript &lt;code&gt;Date&lt;/code&gt; implementation.&lt;/p&gt;

&lt;p&gt;Problems 😵:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No support for time zones other than the user's local time and UTC.&lt;/li&gt;
&lt;li&gt;Parser behavior so unreliable it is unusable.&lt;/li&gt;
&lt;li&gt;Date object is mutable.&lt;/li&gt;
&lt;li&gt;DST behavior is unpredictable.&lt;/li&gt;
&lt;li&gt;Computation APIs are unwieldy.&lt;/li&gt;
&lt;li&gt;No support for non-Gregorian calendars.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Actually some of the issues mentioned are fixable, we just need to add some new factory functions or make APIs to Date. Recently, there is a new API update called &lt;code&gt;Temporal&lt;/code&gt; API that's going to completely revolutionize dates. Currently &lt;code&gt;Temporal&lt;/code&gt; API is in Stage 3 means it's almost finalized. Do check it out and you may report bugs &lt;a href="https://github.com/tc39/proposal-temporal/issues" rel="noopener noreferrer"&gt;here&lt;/a&gt;. As it is still in experimental stage, it shouldn't be use in production.&lt;/p&gt;




&lt;p&gt;The temporal API brings a new global object called &lt;code&gt;Temporal&lt;/code&gt; to JavaScript that includes a lot of new methods and multiple new classes for handling a variety of date based concerns. In this article, I will cover some of the API that I personally think may often use, if you wish to know more about this API, please check out the &lt;a href="https://tc39.es/proposal-temporal/docs/" rel="noopener noreferrer"&gt;full docs&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Temporal API Data Types
&lt;/h2&gt;

&lt;p&gt;There are various different data types introduced in the new temporal API, but the majority of new data types are split between &lt;code&gt;plain&lt;/code&gt; and &lt;code&gt;zoned&lt;/code&gt; version. The only difference between these two types is &lt;code&gt;plain&lt;/code&gt; represents a date/time with no timezone information. A &lt;code&gt;zoned&lt;/code&gt; datetime on the other hand represents a specific date and time in a specific timezone. Besides that, there are also other data types such as &lt;code&gt;Duration&lt;/code&gt;, &lt;code&gt;TimeZone&lt;/code&gt; and &lt;code&gt;Calendar&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  PlainDateTime 📆⌚
&lt;/h3&gt;

&lt;p&gt;It is an object represents a date and time with no timezone information. It uses the current date and time from the timezone you pass to the method, or your current local timezone if no timezone is passed to the method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const today = Temporal.Now.plainDateTimeISO()
console.log(today.toString())
// 2022-04-02T15:54:14.92305492

const date = new Temporal.PlainDateTime(2022, 1, 1)
console.log(date.toString())
// 2022-01-01T00:00:00

const date1 = Temporal.PlainDateTime.from("2022-01-01")
console.log(date1.toString())
// 2022-01-01T00:00:00
const date2 = Temporal.PlainDateTime.from({ year: 2022, month: 1, day: 1 })
console.log(date2.toString())
// 2022-01-01T00:00:00
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PlainDate 📆
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;PlainDate&lt;/code&gt; object represents just a date with no other information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const today = Temporal.Now.plainDateISO()
console.log(today.toString())
// 2022-02-21

const date1 = Temporal.PlainDate.from("2022-01-01")
console.log(date1.toString())
// 2022-01-01
const date2 = Temporal.PlainDate.from({ year: 2022, month: 1, day: 1 })
console.log(date2.toString())
// 2022-01-01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PlainTime ⌚
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;PlainTime&lt;/code&gt; object represents a time that has no timezone and no date.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const today = Temporal.Now.plainTimeISO()
console.log(today.toString())
// 16:09:22.283962281

const time1 = Temporal.PlainTime.from("04:03:25")
console.log(time1.toString())
// 04:03:25
const time2 = Temporal.PlainTime.from({ hour: 4, minute: 3, second: 25 })
console.log(time2.toString())
// 04:03:25
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ZonedDateTime 🗺
&lt;/h3&gt;

&lt;p&gt;A &lt;code&gt;ZonedDateTime&lt;/code&gt; is a datetime that contains all timezone related information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const today = Temporal.Now.zonedDateTimeISO()
console.info(today.toString())
// 2022-04-02T15:54:14.306655305[America/Chicago]

const date1 = Temporal.ZonedDateTime.from("2022-01-01[America/Los_Angeles]")
console.log(date1.toString())
// 2020-01-01T00:00:00-08:00[America/Los_Angeles]

const date2 = Temporal.ZonedDateTime.from({ year: 2022, month: 1, day: 1, timeZone: "America/Los_Angeles" })
console.log(date2.toString())
// 2020-01-01T00:00:00-08:00[America/Los_Angeles]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Instant ⚡
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Instant&lt;/code&gt; is similar to &lt;code&gt;ZonedDateTime&lt;/code&gt; but it is always in UTC time and does not take into account any particular calendar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const today = Temporal.Now.instant()
console.log(today.toString())
// 2022-04-02T08:24:41.434881434Z

const date = Temporal.Instant.from("2022-01-01-06:00")
console.log(date.toString())
// 2022-01-01T06:00:00Z
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PlainMonthDay
&lt;/h3&gt;

&lt;p&gt;Just like &lt;code&gt;PlainDate&lt;/code&gt; but it does not include any year information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const date1 = Temporal.PlainMonthDay.from("01-01")
console.log(date1.toString())
// 01-01
const date2 = Temporal.PlainMonthDay.from({ month: 1, day: 1 })
console.log(date2.toString())
// 01-01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  PlainYearMonth
&lt;/h3&gt;

&lt;p&gt;Just like &lt;code&gt;PlainDate&lt;/code&gt; but it does not include any day information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const date1 = Temporal.PlainYearMonth.from("2022-01")
console.log(date1.toString())
// 2022-01
const date2 = Temporal.PlainYearMonth.from({ year: 2022, month: 1 })
console.log(date2.toString())
// 2022-01
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Helper Methods 🛠
&lt;/h2&gt;

&lt;p&gt;There are a number of helper functions we can use to solve the common use cases such as add or subtract date or date comparison.&lt;/p&gt;

&lt;h3&gt;
  
  
  add ➕ / subtract ➖
&lt;/h3&gt;

&lt;p&gt;As in Javascript, adding or subtracting is really annoying to do, but with temporal API all the data types have built in &lt;code&gt;add&lt;/code&gt; and &lt;code&gt;subtract&lt;/code&gt; methods that make it incredibly easy.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const today = Temporal.Now.plainDateISO()
console.log("Today: " + today.toString())
console.log("Result: " + today.add({ days: 7, months: 1 }).toString())

// Today: 2022-04-02
// Result: 2022-05-09
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  equals
&lt;/h3&gt;

&lt;p&gt;A simple method to check whether two temporal date objects have the exact same fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const today = Temporal.Now.plainDateISO()
const today2 = Temporal.Now.plainDateISO()
console.log(today === today2)
// false
console.log(today.equals(today2))
// true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  with
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;with&lt;/code&gt; method takes in an object of fields to overwrite on the current date object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const today = Temporal.Now.plainDateISO()
console.info(today.toString())
console.log(today.with({ year: 2027, month: 3 }).toString())
// 2022-04-02
// 2027-03-02
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  compare ⚖
&lt;/h3&gt;

&lt;p&gt;As method named, we can use the &lt;code&gt;compare&lt;/code&gt; method to compare with temporal date object or ISO 8601 string.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const today = Temporal.Now.plainDateISO()
const yesterday = today.subtract({ days: 1 })
const tomorrow = '2022-04-03'
console.log([today, yesterday, tomorrow].sort(Temporal.PlainDate.compare))

// [Temporal.PlainDate &amp;lt;2022-04-01&amp;gt;, Temporal.PlainDate &amp;lt;2022-04-02&amp;gt;, '2022-04-03']
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Temporal&lt;/code&gt; API is a great API for JavaScript to deal with dates. There are currently no browsers with any support for this API yet as it is still in proposal stage 3, but you can use a polyfill if you want to try with this API. There are multiple polyfills available for this API, the one I am using is &lt;a href="https://www.npmjs.com/package/@js-temporal/polyfill" rel="noopener noreferrer"&gt;@js-temporal/polyfill&lt;/a&gt;. Thank you for your reading.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>programming</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How easy to setup Master-master replication in CouchDB</title>
      <dc:creator>Jordan Soo Yen Yih</dc:creator>
      <pubDate>Fri, 18 Feb 2022 13:07:06 +0000</pubDate>
      <link>https://dev.to/yenyih/how-easy-to-setup-master-master-replication-in-couchdb-2ijj</link>
      <guid>https://dev.to/yenyih/how-easy-to-setup-master-master-replication-in-couchdb-2ijj</guid>
      <description>&lt;p&gt;Database replication is the process of copying data from a database in one computer or server to a database in another. It is very common if we want to scale our database to increase the availability to access the data. The result is a distributed database in which users can quickly access data relevant to their tasks.&lt;/p&gt;

&lt;p&gt;The most common and classic method of database replication is &lt;strong&gt;Single-leader based data replication&lt;/strong&gt; aka Master-slave Replication - one server that receives writes from clients, and replicas draw data from there. It provides read scalability, reduced latency and better availability as compared to no replication. However, the write of data is not scalable as read. We can only write data to the master node, and read from the slave node. This flaw paves way for multi-leader and leaderless replication.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fel12zttor4rzqv551i5s.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fel12zttor4rzqv551i5s.JPG" alt="master_slave_image" width="592" height="607"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Multi-leader based data replication&lt;/strong&gt; aka Master-master replication, same as single-leader replication, the only different is it has more than one node to accept writes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F21z5zzm6eo35gyyg5xwd.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F21z5zzm6eo35gyyg5xwd.JPG" alt="master_master_image" width="626" height="653"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Today I would like to share about how easy to setup Master-master replication in CouchDB. One of CouchDB's strengths is the ability to synchronize two copies of the same database. We can trigger a replication process by sending a JSON object either to the &lt;code&gt;/_replicate&lt;/code&gt; api endpoint or storing it as a document into the &lt;code&gt;_replicator&lt;/code&gt; database.&lt;/p&gt;

&lt;p&gt;Let say we have a database called &lt;code&gt;cars&lt;/code&gt; in &lt;code&gt;Server A&lt;/code&gt; and we would like to to replicate the &lt;code&gt;cars&lt;/code&gt; database to &lt;code&gt;Server B&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /_replicate

{
   "create_target": false,
   "continuous": false,
   "source": {
      "url": "http://SERVER_A_HOSTNAME:5984/cars",
      "headers": {
         "Authorization": "YOUR_SERVER_A_CREDENTIAL"
      }
   },
   "target": {
      "url": "http://SERVER_B_HOSTNAME:5984/cars",
      "headers": {
         "Authorization": "YOUR_SERVER_B_CREDENTIAL"
      }
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;I personally recommend document based-replication, by storing document to trigger the replication process as you can review back the replication history and you can stop a running replication process by deleting the document, or by updating it with its &lt;code&gt;cancel&lt;/code&gt; property set to &lt;code&gt;true&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For specifying username and password, if you are using CouchDB v3.2.* , there are 3 ways to specify your username and password:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;In an &lt;code&gt;"auth": { "basic": "..." }&lt;/code&gt; object:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "target": {
        "url": "http://someurl.com/mydb",
        "auth": {
            "basic": {
                "username": "$username",
                "password": "$password"
             }
        }
    },
    ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;In the userinfo part of the endpoint URL:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "target":  "http://user:pass@localhost:5984/bar"
    ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;In an "Authorization: Basic $b64encoded_username_and_password" header:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "target": {
        "url": "http://someurl.com/mydb",
            "headers": {
                "Authorization": "Basic dXNlcjpwYXNz"
            }
        },
    ...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you are using the CouchDB earlier version &amp;lt; v3.2, you can only use the second and third method to specify the username and password. Second method is not preferred as it prevents using characters like &lt;code&gt;@&lt;/code&gt; and &lt;code&gt;:&lt;/code&gt; in usernames or passwords.&lt;/p&gt;

&lt;p&gt;After we triggered a replication process, we can inspect CouchDB replication status through the active tasks API &lt;code&gt;/_active_tasks&lt;/code&gt; and &lt;code&gt;/_scheduler/jobs&lt;/code&gt;. For document based-replications, &lt;code&gt;/_scheduler/docs&lt;/code&gt; can be used to get a complete state summary. This API is preferred as it will show the state of the replication document before it becomes a replication job.&lt;/p&gt;

&lt;p&gt;If the database doesn't exist in the target CouchDB server, we can set the &lt;code&gt;create_target&lt;/code&gt; property to &lt;code&gt;true&lt;/code&gt;, it will helps us to create a new database and start replicate the data from the source database. For &lt;code&gt;Master-master replication&lt;/code&gt; setup, we would like to setup a long running replication instead of one time off, just set the &lt;code&gt;continuous&lt;/code&gt; property to &lt;code&gt;true&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /_replicator

{
   "create_target": false,
   "continuous": true,
   "source": {
      "url": "http://SERVER_A_HOSTNAME:5984/cars",
      "headers": {
         "Authorization": "YOUR_SERVER_A_CREDENTIAL"
      }
   },
   "target": {
      "url": "http://SERVER_B_HOSTNAME:5984/cars",
      "headers": {
         "Authorization": "YOUR_SERVER_B_CREDENTIAL"
      }
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we has triggered a &lt;code&gt;continuous database replication&lt;/code&gt; from &lt;code&gt;Server A&lt;/code&gt; to &lt;code&gt;Server B&lt;/code&gt;, then we can trigger one more &lt;code&gt;continuous database replication&lt;/code&gt; from &lt;code&gt;Server B&lt;/code&gt; to &lt;code&gt;Server A&lt;/code&gt; by switching the source and target url.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /_replicator

{
   "create_target": false,
   "continuous": true,
   "source": {
      "url": "http://SERVER_B_HOSTNAME:5984/cars",
      "headers": {
         "Authorization": "YOUR_SERVER_A_CREDENTIAL"
      }
   },
   "target": {
      "url": "http://SERVER_A_HOSTNAME:5984/cars",
      "headers": {
         "Authorization": "YOUR_SERVER_B_CREDENTIAL"
      }
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🎉That's it, now we have both &lt;code&gt;cars&lt;/code&gt; databases in &lt;code&gt;Server A&lt;/code&gt; and &lt;code&gt;Server B&lt;/code&gt; in sync. We can even control which documents to be replicate by using &lt;a href="https://docs.couchdb.org/en/stable/replication/replicator.html#selectorobj" rel="noopener noreferrer"&gt;Selector Objects&lt;/a&gt; or &lt;a href="https://docs.couchdb.org/en/stable/ddocs/ddocs.html#filterfun" rel="noopener noreferrer"&gt;Filter Functions&lt;/a&gt;.&lt;br&gt;
For more detail about CouchDB Replication, please check out the &lt;a href="https://docs.couchdb.org/en/stable/replication/intro.html" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt;. Thank you for reading.&lt;/p&gt;

</description>
      <category>database</category>
      <category>distributedsystems</category>
      <category>replication</category>
    </item>
    <item>
      <title>New Node.js protocol imports</title>
      <dc:creator>Jordan Soo Yen Yih</dc:creator>
      <pubDate>Thu, 20 Jan 2022 12:39:38 +0000</pubDate>
      <link>https://dev.to/yenyih/new-nodejs-protocol-imports-3pnf</link>
      <guid>https://dev.to/yenyih/new-nodejs-protocol-imports-3pnf</guid>
      <description>&lt;p&gt;&lt;code&gt;node:&lt;/code&gt; is a new protocol imports for loading Node.js built-in modules. Actually it has been there for a while since Node.js v12. However I just heard about this few days ago.😲 Let's find out together how to use this new &lt;code&gt;node:&lt;/code&gt; protocol.&lt;/p&gt;

&lt;h3&gt;
  
  
  Previously
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as fs from 'fs/promises';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Now
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as fs from 'node:fs/promises';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Benefits of &lt;code&gt;node:&lt;/code&gt; imports✨
&lt;/h3&gt;

&lt;p&gt;It resolved the conflict of a module (npm-installed) in &lt;code&gt;node_modules&lt;/code&gt; overriding the built-in module. Besides that, it is also clear that a built-in Node.js module is imported.&lt;/p&gt;

&lt;h3&gt;
  
  
  Supported Node.js versions
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;v16.0.0, v14.18.0 (ESM import and CommonJS require())&lt;/li&gt;
&lt;li&gt;v14.13.1, v12.20.0&lt;/li&gt;
&lt;li&gt;Supported in TypeScript by the latest versions of &lt;code&gt;@types/node&lt;/code&gt;(&amp;gt;= v16.0.0).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it, if this is new to you too, hope you find this useful. Thank you for reading. Please check out the &lt;a href="https://nodejs.org/api/esm.html#node-imports" rel="noopener noreferrer"&gt;official documentation&lt;/a&gt; too&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxae1c0orw83ummxqpu1o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxae1c0orw83ummxqpu1o.gif" alt="See_Ya" width="320" height="234"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>programming</category>
    </item>
    <item>
      <title>How to easily deal with domain object in Redis</title>
      <dc:creator>Jordan Soo Yen Yih</dc:creator>
      <pubDate>Wed, 12 Jan 2022 15:16:48 +0000</pubDate>
      <link>https://dev.to/yenyih/how-to-easily-deal-with-domain-object-in-redis-4h0n</link>
      <guid>https://dev.to/yenyih/how-to-easily-deal-with-domain-object-in-redis-4h0n</guid>
      <description>&lt;p&gt;Redis, is a mega fast🚀 Open Source in-memory database often used as a cache and to make traditional databases faster. However, most of the developers don't know that redis can also be used as a primary app database. Thanks to a suite of modules that add additional data structures and commands to core redis. Check out the redis modules &lt;a href="https://redis.io/modules" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;At the end of 2021, Redis announced a preview release of a new high-level client libraries for Redis, called &lt;code&gt;Redis OM&lt;/code&gt;🎉. The main goal is to make developers as easy as possible to use Redis and the Redis modules. Currently it supports for .NET, Node.js, Python, and Java (Spring).&lt;/p&gt;

&lt;p&gt;Today, I would like to share about how to use &lt;code&gt;Redis OM&lt;/code&gt; in Nodejs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation ✨
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save redis-om
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After install, we can import the &lt;code&gt;redis-om&lt;/code&gt; in our Node.js project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Client, Entity, Repository, Schema } from "redis-om"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These are the 4 classes that we will deal a lot.&lt;/p&gt;

&lt;h3&gt;
  
  
  Client Usage 🤝
&lt;/h3&gt;

&lt;p&gt;Client is the main entry point for interacting with Redis. First we initialize a client. Then to connect to our Redis database, we call client open followed by our Redis url.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const client = new Client();

await client.open("redis://&amp;lt;YOUR_REDIS_HOST&amp;gt;:&amp;lt;YOUR_REDIS_PORT&amp;gt;");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If we didn't provide the connection string, by default it uses &lt;code&gt;localhost:6379&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now we ready to talk to redis with the client. Underlying, &lt;code&gt;Redis OM&lt;/code&gt; will automatically helps us to serialize and deserialize our structures to redis.&lt;/p&gt;

&lt;p&gt;However, we still can run basic Redis commands. For example if we want to clean the redis instance, we can use the execute method to run our Redis command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await client.execute(['FLUSHALL']);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To close the redis connection, simply call close method with the client instance.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await client.close();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Entity Usage 👮‍♂️
&lt;/h3&gt;

&lt;p&gt;We can define an entity for our data with the &lt;code&gt;Entity&lt;/code&gt; class. An entity is basically like a database table. For example we can define a class such as Person or Animal, then extend it with &lt;code&gt;Entity&lt;/code&gt; class.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;class Person extends Entity {
  get dateAsISO() { return new Date(this.date).toISOString() }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Inside the class, we can define some custom functions based on use cases. For example we can define a function to convert our data date field to ISO. It is sort of like computed fields we can use after we fetched our data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Schema Usage 📜
&lt;/h3&gt;

&lt;p&gt;After we created an entity, we can give it a schema that contains a variety of different properties each with it own data type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;let schema = new Schema(
   Person,
   {
      name: { type: "string" },
      age: { type: "number" },
      gender: { type: "string" },
      createdAt: { type: "number" }
   },
   {
      dataStructure: "JSON"
   }
)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;By default, the data represents a hash in the redis database. To use the RedisJSON module, add an object with key &lt;code&gt;dataStructure&lt;/code&gt; and value &lt;code&gt;JSON&lt;/code&gt; in the third parameter when initializing the schema.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Repository Usage 🛠
&lt;/h3&gt;

&lt;p&gt;Repository is the one for us to perform Create, Read, Update, and Delete. To create a repository, we need to pass in the schema and the client we created earlier.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const repository = new Repository(schema, client);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create New Data ➕
&lt;/h3&gt;

&lt;p&gt;To create a new data, we can use &lt;code&gt;createEntity&lt;/code&gt; method and pass in a javascript object.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const data = { name: "John Doe", age: 20, gender: "male", createdAt: Date.now() };

const person = repository.createEntity(data);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we can call &lt;code&gt;save&lt;/code&gt; method with the person data to commit into the database and redis will return an automatically generated unique id. &lt;code&gt;Redis OM&lt;/code&gt; is using &lt;a href="https://github.com/ulid/spec" rel="noopener noreferrer"&gt;ULID&lt;/a&gt;s (Universally Unique Lexicographically Sortable Identifiers). You can think of a ULID as a kind of user-friendly UUID. ULIDs are sortable, globally unique, URL-safe, and fairly human-readable when base32-encoded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const id = await repository.save();

console.info(`ID : ${id}`);

// ID : 01ARZ3NDEKTSV4RRFFQ69G5FAV
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Read Data 👀
&lt;/h3&gt;

&lt;p&gt;We can read the data with &lt;code&gt;fetch&lt;/code&gt; method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const person = await repository.fetch(id);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Index 📝
&lt;/h3&gt;

&lt;p&gt;Before we search our data, we need to create an index for our data. we can call &lt;code&gt;createIndex&lt;/code&gt; method with the repository.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Create Index
await repository.createIndex();

// Drop Index
await repository.dropIndex();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Search Data 🔍
&lt;/h3&gt;

&lt;p&gt;Using RediSearch with Redis OM is where the power of this fully armed and operational battle station starts to become apparent. If you have RediSearch installed on your Redis server you can use the search capabilities of &lt;code&gt;Redis OM&lt;/code&gt;. This enables commands like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const oneDay = Date.now() - 24 * 60 * 60 * 1000;

let persons = await repository.search()
  .where('createdAt').is.greaterThan(oneDay)
  .and('name').matches('john')
  .and('age').equals(20).return.all();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Remove Data 🗑
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;await repository.remove(id);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  That's it
&lt;/h2&gt;

&lt;p&gt;Now we can easily create a CRUD application with Redis. Do checkout the &lt;a href="https://github.com/redis/redis-om-node" rel="noopener noreferrer"&gt;&lt;code&gt;redis-om-node&lt;/code&gt;&lt;/a&gt; Github too for more detail on how to use &lt;code&gt;Redis OM&lt;/code&gt; in Node.js.&lt;/p&gt;

</description>
      <category>redis</category>
      <category>database</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>CouchDB clients in Javascript</title>
      <dc:creator>Jordan Soo Yen Yih</dc:creator>
      <pubDate>Sun, 19 Dec 2021 07:42:11 +0000</pubDate>
      <link>https://dev.to/yenyih/couchdb-clients-in-javascript-25d9</link>
      <guid>https://dev.to/yenyih/couchdb-clients-in-javascript-25d9</guid>
      <description>&lt;p&gt;&lt;a href="https://couchdb.apache.org/" rel="noopener noreferrer"&gt;Apache CouchDB&lt;/a&gt; is an open source NoSQL document database that collects and stores data in JSON-based document formats. Since CouchDB makes use of HTTP protocol, therefore we can use any HTTP client to connect with CouchDB. However, there are some existing CouchDB client libraries that are very easy and convenience to use. Below I would like to share 3 libraries that I frequent use to connect with CouchDB.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. &lt;a href="https://github.com/apache/couchdb-nano" rel="noopener noreferrer"&gt;Nano&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;The Offical Apache CouchDB library for Node.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save nano
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Connect to CouchDB server
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const nano = require('nano')('http://localhost:5984');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a new database
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nano.db.create('blogs');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use an existing database
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const blogs = nano.db.use('blogs');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it, easy peasy.😎 Now we can perform some queries with &lt;code&gt;blogs&lt;/code&gt;. &lt;code&gt;nano&lt;/code&gt; underlying is making HTTP API calls to CouchDB service. Such operations are asynchronous, we can use either &lt;code&gt;Promises&lt;/code&gt; or &lt;code&gt;Callbacks&lt;/code&gt; to receive the asynchronous data back from the library.&lt;/p&gt;

&lt;h3&gt;
  
  
  Promises
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;blogs.get('post-A').then(response =&amp;gt; {
  // succeeded
  console.info(response);
}).catch(err =&amp;gt; {
  // failed
  console.error(err)
})
});

// OR

try {
  const response = await blogs.get('post-A')
  // succeeded
  console.log(response)
} catch (e) {
  // failed
  console.error(e)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Callbacks
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;blogs.get('post-A', (err, data) =&amp;gt; {
  // errors are in 'err' &amp;amp; response is in 'data'
})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Nano even supports stream which mean we can proxy the whatever requests from CouchDB to the end user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;blogs.listAsStream()
  .on('error', (e) =&amp;gt; console.error('error', e))
  .pipe(process.stdout)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easy to use.&lt;/li&gt;
&lt;li&gt;CouchDB API compatible.&lt;/li&gt;
&lt;li&gt;Supports Stream.&lt;/li&gt;
&lt;li&gt;The vast majority of library calls return native Promises.&lt;/li&gt;
&lt;li&gt;Detailed TypeScript definitions are built in.&lt;/li&gt;
&lt;li&gt;Easy to debug as errors are proxied directly from CouchDB: if you know CouchDB you already know &lt;code&gt;nano&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Cannot use in browser. Only Nodejs.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. &lt;a href="https://pouchdb.com/" rel="noopener noreferrer"&gt;PouchDB&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;An open-source JavaScript database inspired by Apache CouchDB that is designed to run well within the browser. However, PouchDB also runs in Node.js and can be used as a direct interface to CouchDB-compatible servers. The API works the same in every environment, so you can spend less time worrying about browser differences, and more time writing clean, consistent code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// For browser
npm install pouchdb-browser

// For Node
npm install pouchdb-node
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;PouchDB supports custom builds, meaning you can pick and choose the features of PouchDB that you want to use, potentially resulting in smaller bundle sizes and faster build times. Both &lt;code&gt;pouchdb-browser&lt;/code&gt; and &lt;code&gt;pouchdb-node&lt;/code&gt; contains the replication, HTTP, and map/reduce plugins. I personally prefer pick and choose the features of PouchDB I want instead of using &lt;code&gt;pouchdb-browser&lt;/code&gt; or &lt;code&gt;pouchdb-node&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const PouchDB = require('pouchdb-core')
  .plugin(require('pouchdb-adapter-http'))
  .plugin(require('pouchdb-mapreduce'))
  .plugin(require('pouchdb-replication'));
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Connect to a CouchDB database
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const blogs = new PouchDB('http://localhost:5984/blogs');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a new database
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const blogs = new PouchDB('blogs');
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Query
&lt;/h3&gt;

&lt;p&gt;PouchDB also supports &lt;code&gt;Promises&lt;/code&gt; and &lt;code&gt;Callbacks&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;blogs.get('post-A').then(doc =&amp;gt; {
  // handle doc
}).catch(err =&amp;gt; {
  console.log(err);
});

// OR

try {
  const doc = await blogs.get('post-A');
} catch (err) {
  console.log(err);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;blogs.get('post-A', function(err, doc) {
  if (err) { return console.log(err); }
  // handle doc
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Easy to learn &amp;amp; use.&lt;/li&gt;
&lt;li&gt;Works in all modern browsers and Nodejs.&lt;/li&gt;
&lt;li&gt;Lightweight&lt;/li&gt;
&lt;li&gt;Support Offline&lt;/li&gt;
&lt;li&gt;Support Custom Builds / Plugins&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Not fully support CouchDB API, one of the example is you cannot use CouchDB's &lt;code&gt;update function&lt;/code&gt; via PouchDB.&lt;/li&gt;
&lt;li&gt;Official library doesn't come with Stream. However, since PouchDB supports custom builds, you still can do stream with external PouchDB projects.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;There is a a list of known plugins, tools and projects can be used with PouchDB. You can find it &lt;a href="https://pouchdb.com/external.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  3. &lt;a href="https://github.com/axios/axios" rel="noopener noreferrer"&gt;Axios&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;If you are a javascript developer, you should probably already know about axios. It is a Promise based HTTP client for the browser and node.js.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install --save axios
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Connect to CouchDB server
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const couchdb = axios.create({
  baseURL: 'http://localhost:5984',
  timeout: 1000,
  headers: { 'X-Custom-Header': 'foobar'}
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a new database
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;couchdb.put('/blogs').then(response =&amp;gt; {
  // succeeded
}).catch(err =&amp;gt; {
  // failed
});

// OR

try {
  const response = await couchdb.put('/blogs');
  console.info(response.data);
} catch (err) {
  console.error(err);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Query
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;couchdb.get('/blogs/post-A').then(response =&amp;gt; {
  console.info(response.data);
}).catch(err =&amp;gt; {
  console.error(err);
});

// OR

try {
  const response = await couchdb.get('/blogs/post-A');
  console.info(response.data);
} catch (err) {
  console.error(err);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pros:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Works in all modern browsers and Nodejs.&lt;/li&gt;
&lt;li&gt;Supports the Promise API&lt;/li&gt;
&lt;li&gt;Intercept request and response&lt;/li&gt;
&lt;li&gt;Transform request and response data&lt;/li&gt;
&lt;li&gt;Cancel requests&lt;/li&gt;
&lt;li&gt;Automatic transforms for JSON data&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Cons:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Codes are not as clean/minimal as PouchDB. In order to achieve minimal of code with axios, you will need to spend extra time to build your own factory functions on top of axios.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Thanks for Reading.
&lt;/h2&gt;

&lt;p&gt;If you know any other interesting libraries that play well with CouchDB, please leave comments below to share with me. Thank you.☺&lt;/p&gt;

</description>
      <category>database</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>10 useful Git tips to improve your workflow</title>
      <dc:creator>Jordan Soo Yen Yih</dc:creator>
      <pubDate>Sat, 11 Dec 2021 12:20:02 +0000</pubDate>
      <link>https://dev.to/yenyih/10-useful-git-tips-to-improve-your-workflow-kf1</link>
      <guid>https://dev.to/yenyih/10-useful-git-tips-to-improve-your-workflow-kf1</guid>
      <description>&lt;p&gt;&lt;a href="https://git-scm.com/" rel="noopener noreferrer"&gt;Git&lt;/a&gt; is a free and open source distributed version control system designed to handle everything from small to very large projects with speed and efficiency. &lt;/p&gt;

&lt;p&gt;Whether you’re just getting started with Git, or you know your way around a command line, it’s always nice to brush up on your skills. Below I would like to share 10 useful Git tips to improve your Git-based workflow.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Git aliases 🏷
&lt;/h2&gt;

&lt;p&gt;Create your own aliases for common commands to save you some time in the terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global alias.co checkout
git config --global alias.ci commit
git config --global alias.br branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of typing &lt;code&gt;git checkout master&lt;/code&gt;, you only need to type &lt;code&gt;git co master&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You could also edit these commands or add more by modifying the &lt;code&gt;~/.gitconfig&lt;/code&gt; file directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[alias]
    co = checkout
    ci = commit
    br = branch
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Compare commits ⚖
&lt;/h2&gt;

&lt;p&gt;A simple way to compare the differences between commits or versions of the same file is to use the &lt;code&gt;git diff&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;If you want to compare the same file between different commits, you run the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git diff $start_commit..$end_commit -- path/to/file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to compare the changes between two commits:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git diff $start_commit..$end_commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These commands will open the diff view inside the terminal, but if you prefer to use a more visual tool to compare your diffs, you can use &lt;code&gt;git difftool&lt;/code&gt;. &lt;a href="https://meldmerge.org/" rel="noopener noreferrer"&gt;Meld&lt;/a&gt; is a useful viewer/editor to visually compare diffs.&lt;/p&gt;

&lt;p&gt;To configure Meld:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global diff.tool git-meld
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To start viewing the diffs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git difftool $start_commit..$end_commit -- path/to/file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git difftool $start_commit..$end_commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Stashing uncommitted changes 🔖
&lt;/h2&gt;

&lt;p&gt;If you’re ever working on a feature and need to do an emergency fix on the project, you could run into a problem.😰 You don’t want to commit an unfinished feature, and you also don’t want to lose current changes. The solution is to temporarily remove these changes with the Git stash command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git stash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The git stash command hides changes, giving you a clean working directory and the ability to switch to a new branch to make updates, without having to commit a meaningless snapshot in order to save the current state.&lt;/p&gt;

&lt;p&gt;Once you’re done working on a fix and want to revisit your previous changes, you can run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git stash pop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And your changes will be recovered. 🎉&lt;/p&gt;

&lt;p&gt;If you no longer need those changes and want to clear the stash stack, you can do so with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git stash drop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Pull frequently 📥
&lt;/h2&gt;

&lt;p&gt;In order to avoid major conflicts, you should frequently pull the changes from the master branch to your branch to resolve any conflicts as soon as possible and to make merging your branch to master easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Autocomplete commands 🤖
&lt;/h2&gt;

&lt;p&gt;Using &lt;a href="https://github.com/git/git/tree/master/contrib/completion" rel="noopener noreferrer"&gt;completion scripts&lt;/a&gt;, you can quickly create the commands for &lt;code&gt;bash&lt;/code&gt;, &lt;code&gt;tcsh&lt;/code&gt; and &lt;code&gt;zsh&lt;/code&gt;. If you want to type &lt;code&gt;git pull&lt;/code&gt;, you can type just the first letter with &lt;code&gt;git p&lt;/code&gt; followed by &lt;code&gt;Tab&lt;/code&gt; will show the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pack-objects   -- create packed archive of objects
pack-redundant -- find redundant pack files
pack-refs      -- pack heads and tags for efficient repository access
parse-remote   -- routines to help parsing remote repository access parameters
patch-id       -- compute unique ID for a patch
prune          -- prune all unreachable objects from the object database
prune-packed   -- remove extra objects that are already in pack files
pull           -- fetch from and merge with another repository or local branch
push           -- update remote refs along with associated objects
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To show all available commands, type &lt;code&gt;git&lt;/code&gt; in your terminal followed by &lt;code&gt;Tab&lt;/code&gt; + &lt;code&gt;Tab&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Set a global &lt;code&gt;.gitignore&lt;/code&gt; 🚫
&lt;/h2&gt;

&lt;p&gt;If you want to avoid committing files like &lt;code&gt;.DS_Store&lt;/code&gt; or Vim &lt;code&gt;swp&lt;/code&gt; files, you can set up a global &lt;code&gt;.gitignore&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;Create the file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch ~/.gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global core.excludesFile ~/.gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or manually add the following to your &lt;code&gt;~/.gitconfig&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[core]
  excludesFile = ~/.gitignore
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can create a list of the things you want Git to ignore. To learn more, visit the &lt;a href="https://git-scm.com/docs/gitignore" rel="noopener noreferrer"&gt;gitignore documentation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Delete local branches that have been removed from remote on fetch/pull 🗑
&lt;/h2&gt;

&lt;p&gt;You likely have stale branches in your local repository that no longer exist in the remote one. To delete them in each fetch/pull, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global fetch.prune true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or manually add the following to your &lt;code&gt;~/.gitconfig&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[fetch]
  prune = true
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  8. Use Git blame more efficiently 🕵️‍♂️
&lt;/h2&gt;

&lt;p&gt;Git blame is a handy way to discover who changed a line in a file. Depending on what you want to show, you can pass different flags:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git blame -w  # ignores white space

git blame -M  # ignores moving text

git blame -C  # ignores moving text into other files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  9. An alias of &lt;code&gt;HEAD&lt;/code&gt; 👀
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;@&lt;/code&gt; is the same as &lt;code&gt;HEAD&lt;/code&gt;. Using it during a rebase is a lifesaver:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git rebase -i @~2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  10. Resetting files ↩
&lt;/h2&gt;

&lt;p&gt;You’re modifying your code when you suddenly realize that the changes you made are not great, and you’d like to reset them. Rather than clicking undo on everything you edited, you can reset your files to the HEAD of the branch&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git reset --hard HEAD
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or if you want to reset a single file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git checkout HEAD -- path/to/file
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, if you already committed your changes, but still want to revert back, you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git reset --soft HEAD~1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Extras: ✨
&lt;/h2&gt;

&lt;p&gt;If you want to elevate Git with more commands, try out the &lt;a href="https://github.com/tj/git-extras" rel="noopener noreferrer"&gt;git-extras plugin&lt;/a&gt;, which includes &lt;code&gt;git info&lt;/code&gt; (show information about the repository) and &lt;code&gt;git effort&lt;/code&gt; (number of commits per file).&lt;/p&gt;

</description>
      <category>git</category>
      <category>beginners</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How to setup Clouseau for CouchDB search on Unix-like systems</title>
      <dc:creator>Jordan Soo Yen Yih</dc:creator>
      <pubDate>Tue, 23 Nov 2021 13:40:36 +0000</pubDate>
      <link>https://dev.to/yenyih/how-to-setup-clouseau-for-couchdb-search-on-unix-like-systems-14gj</link>
      <guid>https://dev.to/yenyih/how-to-setup-clouseau-for-couchdb-search-on-unix-like-systems-14gj</guid>
      <description>&lt;h2&gt;
  
  
  Introduction
&lt;/h2&gt;

&lt;p&gt;Clouseau is written in Scala code and provides access to the Lucene library. You can use &lt;a href="http://lucene.apache.org/core/4_3_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#Overview" rel="noopener noreferrer"&gt;Lucene Query Syntax&lt;/a&gt; to run search queries. In previous article I did talk about we can &lt;a href="https://dev.to/yenyih/query-in-apache-couchdb-clouseau-41ll"&gt;query in Apache CouchDB with Clouseau&lt;/a&gt;, today I would like to talk about how to setup Clouseau that link with CouchDB.&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites📜
&lt;/h2&gt;

&lt;p&gt;Before you begin this guide, you should have a regular, non-root user with sudo privileges configured on your server. Additionally, you will need to have a up and running &lt;strong&gt;CouchDB version v3+&lt;/strong&gt; on your server. You can learn how to install Apache CouchDB on Unix-like systems by following the official documentation &lt;a href="https://docs.couchdb.org/en/stable/install/unix.html#installation-using-the-apache-couchdb-convenience-binary-packages" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Besides that, since Clouseau is written in Scala, we also need to install Java to run Clouseau.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The search plugin is runtime-compatible with Java JDKs 6, 7 and 8. Building a release from source requires JDK 6. &lt;strong&gt;It will not work with any newer version of Java&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In this tutorial, I am using &lt;strong&gt;Ubuntu 20.04&lt;/strong&gt;, &lt;strong&gt;JDK 8&lt;/strong&gt; and &lt;strong&gt;CouchDB v3.2.1&lt;/strong&gt; . CouchDB v3 and higher is a must as CouchDB v3 has extremely simplified the setup of Lucene search.&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F816pp70rdud8c3xddk56.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F816pp70rdud8c3xddk56.JPG" alt="server" width="655" height="523"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuwd6on9ydt58p021zb43.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fuwd6on9ydt58p021zb43.JPG" alt="initial_couchdb_status" width="753" height="448"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzcvqz7ula8nmcjf0zi9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhzcvqz7ula8nmcjf0zi9.gif" alt="lets_begin" width="480" height="360"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  1. Download Clouseau
&lt;/h2&gt;

&lt;p&gt;You can download the latest Clouseau release from &lt;a href="https://github.com/cloudant-labs/clouseau/releases" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Your Clouseau might be different depending on the time you download. My current latest version is Clouseau 2.17.0. I am using &lt;em&gt;wget&lt;/em&gt; to download from my Ubuntu server.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo wget https://github.com/cloudant-labs/clouseau/releases/download/2.17.0/clouseau-2.17.0-dist.zip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. Extract Clouseau zip
&lt;/h2&gt;

&lt;p&gt;We are using &lt;em&gt;unzip&lt;/em&gt; to extract the Clouseau jar files.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tips: If you don't have unzip, you can run the command &lt;em&gt;&lt;strong&gt;sudo apt-get install unzip&lt;/strong&gt;&lt;/em&gt; for Ubuntu.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then, we can unzip it with the command below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo unzip clouseau-2.17.0-dist.zip -d /opt/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see, we extract the Clouseau to the destination /opt/&lt;br&gt;
. Now we can navigate to the extracted destination and view the extracted files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /opt/clouseau-2.17.0/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  3. Create Configuration files
&lt;/h2&gt;

&lt;p&gt;According to CouchDB official documentation, in order to setup the search plugin, there are 2 configuration files required called &lt;em&gt;&lt;strong&gt;clouseau.ini&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;log4j.properties&lt;/strong&gt;&lt;/em&gt; with the following content:&lt;/p&gt;

&lt;h3&gt;
  
  
  clouseau.ini
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[clouseau]

; the name of the Erlang node created by the service, leave this unchanged
name=clouseau@127.0.0.1

; set this to the same distributed Erlang cookie used by the CouchDB nodes
cookie=monster

; the path where you would like to store the search index files
dir=/opt/couchdb/share/

; the number of search indexes that can be open simultaneously
max_indexes_open=500
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  log4j.properties
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;log4j.rootLogger=debug, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %c [%p] %m%n
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. Create a script to run Clouseau
&lt;/h2&gt;

&lt;p&gt;Below is the script to run Clouseau. If you have a Java background, below syntax should be familiar for you. In this case, I will place the script file under &lt;em&gt;/opt/clouseau-2.17.0/bin/&lt;/em&gt; and the file name called &lt;em&gt;clouseau&lt;/em&gt;, full path would be &lt;em&gt;/opt/clouseau-2.17.0/bin/clouseau&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/bin/sh
/usr/bin/java -server \
     -Xmx2G \
     -Dsun.net.inetaddr.ttl=30 \
     -Dsun.net.inetaddr.negative.ttl=30 \
     -Dlog4j.configuration=file:/opt/clouseau-2.17.0/log4j.properties \
     -XX:OnOutOfMemoryError="kill -9 %p" \
     -XX:+UseConcMarkSweepGC \
     -XX:+CMSParallelRemarkEnabled \
     -classpath '/opt/clouseau-2.17.0/*' \
     com.cloudant.clouseau.Main \
     /opt/clouseau-2.17.0/clouseau.ini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Your path could be different, it depends on where you put the clouseau files, you could change the &lt;em&gt;&lt;strong&gt;/opt/clouseau-2.17.0/&lt;/strong&gt;&lt;/em&gt; if needed, in this case, I'm putting all the clouseau files and configurations under &lt;em&gt;/opt/clouseau-2.17.0&lt;/em&gt; directories.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We are almost there. Now we want to tell Ubuntu to run the service when the server startup. To do that, we can navigate to &lt;em&gt;&lt;strong&gt;/lib/systemd/system&lt;/strong&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd /lib/systemd/system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and create a file called &lt;em&gt;&lt;strong&gt;clouseau.service&lt;/strong&gt;&lt;/em&gt; with the content below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[Unit]
Description=clouseau service

[Service]
WorkingDirectory=/opt/clouseau-2.17.0
ExecStart=/opt/clouseau-2.17.0/bin/clouseau
Restart=always
RestartSec=3
User=root

[Install]
WantedBy=multi-user.target
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once created, then run the 3 commands below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl daemon-reload
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl enable clouseau.service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl start clouseau
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then, Clouseau should already be up and running. Check with the systemd init system to make sure the service is running by typing&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sudo systemctl status apache2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Finally, we can check whether our Apache CouchDB and Clouseau is connected by using CouchDB root endpoint.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;curl 127.0.0.1:5984
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57kdgi0r48fyl6onugmw.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57kdgi0r48fyl6onugmw.JPG" alt="final_couchdb_status" width="760" height="350"&gt;&lt;/a&gt;&lt;br&gt;
If Clouseau is connected to CouchDB successfully, You should see the &lt;em&gt;&lt;strong&gt;search&lt;/strong&gt;&lt;/em&gt; keyword display under &lt;em&gt;&lt;strong&gt;features&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  That's it, we did it~🎉
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxftc7av38tucj3is3p4.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkxftc7av38tucj3is3p4.gif" alt="hooray" width="500" height="348"&gt;&lt;/a&gt;&lt;br&gt;
Now we can query with Lucene Query Syntax in CouchDB.&lt;br&gt;
Hope you find this guide useful.👋&lt;/p&gt;

</description>
      <category>database</category>
      <category>tutorial</category>
      <category>beginners</category>
      <category>ubuntu</category>
    </item>
    <item>
      <title>CSS Variables</title>
      <dc:creator>Jordan Soo Yen Yih</dc:creator>
      <pubDate>Sat, 20 Nov 2021 11:13:02 +0000</pubDate>
      <link>https://dev.to/yenyih/css-variables-k5</link>
      <guid>https://dev.to/yenyih/css-variables-k5</guid>
      <description>&lt;p&gt;&lt;strong&gt;CSS variables&lt;/strong&gt; aka &lt;strong&gt;custom properties&lt;/strong&gt; allows you to reuse values throughout your stylesheet. It increases your efficiency, reduce code duplication and a lot of cool tricks you could do with them.🤩&lt;/p&gt;




&lt;h2&gt;
  
  
  Global Variables
&lt;/h2&gt;

&lt;p&gt;We can define global variables that will be use throughout the entire website on the root element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:root {
   --warning-color: yellow; 

   /* Format --&amp;lt;YOUR_VARIABLE_NAME&amp;gt;: &amp;lt;ANY_CSS_VALUE&amp;gt; */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start with the double dash, followed by whatever name you want to use for the variable. Then you can use any valid CSS value.&lt;/p&gt;

&lt;p&gt;Then you can use the variable with the &lt;em&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;/em&gt; function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;body {
   color: var(--warning-color);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Tips: When calling a CSS variable with the &lt;em&gt;&lt;strong&gt;var&lt;/strong&gt;&lt;/em&gt; function, You can pass in a second argument as a fallback value.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;body {
   color: var(--warning-color, red);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As example above, if the variable is undefined or invalid CSS value, then it will use red instead.&lt;/p&gt;

&lt;p&gt;Now by using the CSS Variables, when we want to change the value, we just need to update once instead of go through every places.&lt;/p&gt;

&lt;h2&gt;
  
  
  Variable Cascade Downwards
&lt;/h2&gt;

&lt;p&gt;We can override the Global CSS variables value in the children. Let's say we have a global variable in previous example, and we have a &lt;em&gt;card&lt;/em&gt; class that change the --warning-color variable to red. So the HTML element with this &lt;em&gt;card&lt;/em&gt; class will use the red value instead of yellow value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/* Global */
:root {
   --warning-color: yellow;
}

/* Local */
.card {
   --warning-color: red;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That means we can change the appearance of our website by simply tweaking CSS Variables value. This concept very powerful when combine with &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Media_Queries/Using_media_queries" rel="noopener noreferrer"&gt;Media Queries&lt;/a&gt;💪.&lt;/p&gt;

&lt;p&gt;For example if the viewport is smaller, you may want to decrease the margin between HTML elements instead of updating potential more than 100 CSS classes😵🤯, just define a media query and change the CSS variables value.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@media screen and (min-width: 600px) {
   :root {
      --margin-base: 10px;
   }
}

/* Small Screens */
@media screen and (max-width: 600px) {
   :root {
      --margin-base: 6px;
   }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another example is we can use the &lt;em&gt;prefers-color-scheme&lt;/em&gt; media query to toggle between light theme and dark theme based on the user's device preferences.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@media (prefers-color-scheme: dark) {
    :root {
       --text-color: white;
       --background-color: black;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Besides that, CSS variables also work great with &lt;em&gt;&lt;em&gt;calc&lt;/em&gt;&lt;/em&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.my-title {
   --regular-number: 8;

   margin: calc( var(--regular-number) * 1px );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Besides that, you are not limited to use a single variable in a property value. For example below we can define several variables.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;:root {
   --red: 86;
   --green: 23;
   --blue: 107;
}

.content-card {
   color: rgb( var(--red), var(--green), var(--blue) );
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes CSS Variables extremely useful on building themes. This is because when we combine with Javascript and change the CSS classes on the fly, then the browser will automatically repaint the style of the website.✨🤩&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wfeosg8cigqsoyya0eq.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3wfeosg8cigqsoyya0eq.gif" alt="thank_you_gif" width="480" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Thanks for reading.
&lt;/h2&gt;

&lt;p&gt;Above is what I learnt about CSS Variables and how to apply them. If you have any other interesting way on using CSS Variables, please comment below to share with me.🙏😊&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>css</category>
      <category>beginners</category>
      <category>programming</category>
    </item>
    <item>
      <title>Query in Apache CouchDB: Clouseau</title>
      <dc:creator>Jordan Soo Yen Yih</dc:creator>
      <pubDate>Mon, 15 Nov 2021 13:14:01 +0000</pubDate>
      <link>https://dev.to/yenyih/query-in-apache-couchdb-clouseau-41ll</link>
      <guid>https://dev.to/yenyih/query-in-apache-couchdb-clouseau-41ll</guid>
      <description>&lt;p&gt;In previous articles, we have talk about how to query with CouchDB Views and Mango Query. Both methods are working very well and able to cover a lot of use cases. Why Clouseau?&lt;/p&gt;

&lt;p&gt;There are still very limited for CouchDB Views and Mango Query when we talk about search, there are a lot of complex searching required which makes the Views function and Mango Index more complex and harder to build, at the same time need to have a great search performance. You are still able to build your own search engine from scratch with Mango and Views. However it is very tough and you have to put a lot of resources to build a good search engine, ton of work like text preprocessing, tokenization, algorithm, ranking and etc...😰&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5z4wlkbl16xv63b0qa8x.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5z4wlkbl16xv63b0qa8x.gif" alt="out_of_control_gif" width="499" height="499"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Thanks to Clouseau brought CouchDB search to the next level🥳
&lt;/h2&gt;

&lt;p&gt;Start from CouchDB v3, CouchDB can build and query full-text search indexes using an external Java service that embeds Apache Lucene. If you have been already familiar with Elasticsearch, then it is very easy for you to catch up with CouchDB + Clouseau as they are using the same Lucene Syntax.&lt;/p&gt;
&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;To setup Clouseau works together with CouchDB, you may refer to my &lt;a href="https://dev.to/yenyih/how-to-setup-clouseau-for-couchdb-search-on-unix-like-systems-14gj"&gt;tutorial post&lt;/a&gt; or the official docs &lt;a href="https://docs.couchdb.org/en/stable/install/search.html#install-search" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  How to use?
&lt;/h2&gt;

&lt;p&gt;It is like Mango Query, create a design document for the search index function, then search with the index function.&lt;/p&gt;

&lt;p&gt;Example Search Index Function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function(document) {
    index("default", document._id);
    if (document.title) {
        index("title", document.title, {"store": true});
    }
    if (document.status) {
        index("status", document.status, { "store": false });
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Design Document in full view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "_id": "_design/search",
  "_rev": "1-15807c8c7e310b566c0a41997d79b7fd",
  "views": {},
  "language": "javascript",
  "indexes": {
    "posts": {
      "analyzer": "standard",
      "index": "function(doc) {\r\n    index(\"default\", doc._id);\r\n    if (doc.status) {\r\n        index(\"status\", doc.status, { \"store\": false });\r\n    }\r\n    if (doc.title) {\r\n        index(\"title\", doc.title, {\"store\": true});\r\n    }\r\n}"
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Above search index function allows us to search with document ID, title and status. By default it is searching with document ID if we didn't provide any key. The &lt;em&gt;"store"&lt;/em&gt; with boolean we pass in in the third argument is to indicate whether you want to return the value in the search result, the default value is false.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /YOUR_DATABASE_NAME/_design/search/_search/posts?q=ea885d7d-7af2-4858-b7bf-6fd01bcd4544
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "total_rows": 1,
  "bookmark": "g2wAAAABaANkABFjb3VjaGRiQDEyNy4wLjAuMWwAAAACYQBuBAD_____amgCRj_6gH-AAAAAYQFq",
  "rows": [
    {
      "id": "ea885d7d-7af2-4858-b7bf-6fd01bcd4544",
      "order": [
        1.6563715934753418,
        1
      ],
      "fields": {
        "title": "Post Two Title"
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let us try to search with post's status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /YOUR_DATABASE_NAME/_design/search/_search/posts?q=status:submitted
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "total_rows": 2,
  "bookmark": "g2wAAAABaANkABFjb3VjaGRiQDEyNy4wLjAuMWwAAAACYQBuBAD_____amgCRj_0mliAAAAAYQJq",
  "rows": [
    {
      "id": "c2ec3b79-d9ac-45a8-8c68-0f05cb3adfac",
      "order": [
        1.287682056427002,
        0
      ],
      "fields": {
        "title": "Post One Title"
      }
    },
    {
      "id": "4a2348ca-f27c-427f-a490-e29f2a64fdf2",
      "order": [
        1.287682056427002,
        2
      ],
      "fields": {
        "title": "Post Three Title"
      }
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Analyzers📈
&lt;/h2&gt;

&lt;blockquote&gt;
&lt;p&gt;Analyzers are settings that define how to recognize terms within text. Analyzers can be helpful if you need to &lt;a href="https://docs.couchdb.org/en/stable/ddocs/search.html#ddoc-search-language-specific-analyzers" rel="noopener noreferrer"&gt;index multiple languages&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are 6 analyzers that are supported by the search:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;classic&lt;/strong&gt; - The standard Lucene analyzer, circa release 3.1.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;email&lt;/strong&gt; - Like the &lt;em&gt;standard&lt;/em&gt; analyzer, but tries harder to match an email address as a complete token.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;keyword&lt;/strong&gt; - Input is not tokenized at all.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;simple&lt;/strong&gt; - Divides text at non-letters.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;standard&lt;/strong&gt; - The default analyzer. It implements the Word Break rules from the &lt;a href="http://www.unicode.org/reports/tr29/" rel="noopener noreferrer"&gt;Unicode Text Segmentation algorithm&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;whitespace&lt;/strong&gt; - Divides text at white space boundaries.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Based on your use cases to pick the suitable analyzer for your search index.&lt;/p&gt;

&lt;h2&gt;
  
  
  Geographical Searches🗺
&lt;/h2&gt;

&lt;p&gt;Besides that, you can also do geographical searches in CouchDB with Lucene's built-in geospatial capabilities.😍&lt;/p&gt;

&lt;p&gt;Example geographical data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "name":"Aberdeen, Scotland",
    "lat":57.15,
    "lon":-2.15,
    "type":"city"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example search index for the geographic data:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function(doc) {
    if (doc.type &amp;amp;&amp;amp; doc.type == 'city') {
        index('city', doc.name, {'store': true});
        index('lat', doc.lat, {'store': true});
        index('lon', doc.lon, {'store': true});
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;HTTP Request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GET /YOUR_DATABASE_NAME/_design/YOUR_DESIGN_DOC_NAME/_search/SEARCH_INDEX_NAME?q=lat:[0+TO+90]&amp;amp;sort="&amp;lt;distance,lon,lat,-74.0059,40.7127,km&amp;gt;"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Abbreviated Result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "total_rows": 205,
    "bookmark": "g1A...XIU",
    "rows": [
        {
            "id": "city180",
            "order": [
                8.530665755719783,
                18
            ],
            "fields": {
                "city": "New York, N.Y.",
                "lat": 40.78333333333333,
                "lon": -73.96666666666667
            }
        },
        {
            "id": "city177",
            "order": [
                13.756343205985946,
                17
            ],
            "fields": {
                "city": "Newark, N.J.",
                "lat": 40.733333333333334,
                "lon": -74.16666666666667
            }
        },
        {
            "id": "city178",
            "order": [
                113.53603438866077,
                26
            ],
            "fields": {
                "city": "New Haven, Conn.",
                "lat": 41.31666666666667,
                "lon": -72.91666666666667
            }
        }
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Thank you for reading.
&lt;/h2&gt;

&lt;p&gt;There are more you can do with CouchDB search. Do checkout the official documentation &lt;a href="https://docs.couchdb.org/en/stable/ddocs/search.html" rel="noopener noreferrer"&gt;here&lt;/a&gt; and also &lt;a href="https://lucene.apache.org/core/4_3_0/queryparser/org/apache/lucene/queryparser/classic/package-summary.html#Overview" rel="noopener noreferrer"&gt;Lucene Syntax&lt;/a&gt; as CouchDB search query syntax is using the Lucene Syntax.😊&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4sl9lfxeybit04rvku20.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4sl9lfxeybit04rvku20.gif" alt="thats_all_folk" width="499" height="366"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>database</category>
      <category>beginners</category>
      <category>node</category>
    </item>
    <item>
      <title>Query in Apache CouchDB: Mango Query</title>
      <dc:creator>Jordan Soo Yen Yih</dc:creator>
      <pubDate>Sun, 31 Oct 2021 03:38:48 +0000</pubDate>
      <link>https://dev.to/yenyih/query-in-apache-couchdb-mango-query-lfd</link>
      <guid>https://dev.to/yenyih/query-in-apache-couchdb-mango-query-lfd</guid>
      <description>&lt;p&gt;In previous articles, we talked about design documents and how to use views to query in CouchDB. Besides Javascript query server, CouchDB also has a built-in Mango query server for us to query documents. Therefore in this article, I will talk about what is Mango Query, and when to use Mango Query?&lt;/p&gt;




&lt;h2&gt;
  
  
  What is Mango 🥭?
&lt;/h2&gt;

&lt;p&gt;Mango is a MongoDB inspired query language interface for Apache CouchDB.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Mango provides a single HTTP API endpoint that accepts JSON bodies via HTTP POST. These bodies provide a set of instructions that will be handled with the results being returned to the client in the same order as they were specified. The general principle of this API is to be simple to implement on the client side while providing users a more natural conversion to Apache CouchDB than would otherwise exist using the standard RESTful HTTP interface that already exists.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  How to use mango query in CouchDB?
&lt;/h2&gt;

&lt;p&gt;We use back the same use case example in previous articles (A list of blog posts):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    _id: "c2ec3b79-d9ac-45a8-8c68-0f05cb3adfac",
    title: "\"Post One Title\","
    content: "Post one content.",
    author: "John Doe",
    status: "submitted",
    date: "2021-10-30T14:57:05.547Z",
    type: "post"
  },
  {
    _id: "ea885d7d-7af2-4858-b7bf-6fd01bcd4544",
    title: "\"Post Two Title\","
    content: "Post two content.",
    author: "Jane Doe",
    status: "draft",
    date: "2021-09-29T08:37:05.547Z",
    type: "post"
  },
  {
    _id: "4a2348ca-f27c-427f-a490-e29f2a64fdf2",
    title: "\"Post Three Title\","
    content: "Post three content.",
    author: "John Doe",
    status: "submitted",
    date: "2021-08-02T05:31:05.547Z",
    type: "post"
  },
  ...
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to query the posts with status draft, we can define the mango query as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "selector": {
        "status": { "$eq": "draft" }
    },
    "fields": ["_id", "_rev", "title", "content", "date", "author"],
    "sort": [],
    "limit": 10,
    "skip": 0,
    "execution_stats": true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Let's us break down line by line before we submit our mango query.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Selector 🔎
&lt;/h3&gt;

&lt;p&gt;This is the place you define your query condition, you can give it a document property key that you want to query and the result. With the example above we want to query documents with status "draft", so we can make use of the operator equal &lt;em&gt;$eq&lt;/em&gt; .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"selector": {
   "status": { "$eq": "draft" }
}

// If it is an equal operator, we also can define as below too

"selector": {
   "status": "draft"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Fields 🎁
&lt;/h3&gt;

&lt;p&gt;Sometimes you might just required a property value, or your document might be a big JSON document or you are working for mobile client that you want to optimize the query result download size. Therefore, fields is handy for us to tell CouchDB just return what property fields to us. Just like GraphQL, get what you needed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"fields": ["_id", "_rev", "title", "content", "date", "author"],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Tips: Fields is Optional, if you didn't define fields, CouchDB will just return the whole document to you.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  3. Sort, Limit, Skip
&lt;/h3&gt;

&lt;p&gt;These are normal useful feature that you can do in other normal database. They are optional too.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"sort": [],
"limit": 10,
"skip": 0,
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;*Note: For limit by default is 25, however there is an internal maximum limit which is around 250 number of documents with a Mango Query request. Therefore, if you didn't define the limit or even set the limit to 1k, it will still return around 250 documents. To solve this issue, either use CouchDB Views for this particular query or use Bookmark (We will talk about bookmark later).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  4. Execution Statistics
&lt;/h3&gt;

&lt;p&gt;This is a nice feature for developer to know the basic execution statistics for the specific mango query request. It is Optional too.&lt;/p&gt;

&lt;p&gt;And then we can post our mango query to&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /{YOUR_DATABASE_NAME}/_find
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{ 
   "docs": [
     {
         "_id": "ea885d7d-7af2-4858-b7bf-6fd01bcd4544",
         "_rev": "1-f9397a0bc5b6150270b5309db35ec4b9",
         "title": "Post Two Title",
         "content": "Post two content.",
         "date":"2021-09-29T08:37:05.547Z",
         "author":"Jane Doe"
      }
    ],
    "bookmark": "g1AAAAB4eJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYqrpCZaWJimmKfomiemGemaWJha6CaZJ6XpmqWlGBgmJaeYmJqYgPRywPQSrSsLAKuSIMM",
    "execution_stats": {
       "total_keys_examined":0,
       "total_docs_examined":1,
       "total_quorum_docs_examined":0,
       "results_returned":1,
       "execution_time_ms":2.253
    },
    "warning": "no matching index found, create an index to optimize query time"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;p&gt;Let's us take a look at the result.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Docs 📃
&lt;/h3&gt;

&lt;p&gt;Here is the result we got from Mango Query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"docs": [
     {
         "_id": "ea885d7d-7af2-4858-b7bf-6fd01bcd4544",
         "_rev": "1-f9397a0bc5b6150270b5309db35ec4b9",
         "title": "Post Two Title",
         "content": "Post two content.",
         "date":"2021-09-29T08:37:05.547Z",
         "author":"Jane Doe"
      }
    ],
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Bookmark 🔖
&lt;/h3&gt;

&lt;p&gt;This is the bookmark we mentioned earlier. Bookmark from official document is&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A string that enables us to specify which page of results we require. Used for paging through result sets. Every query returns an opaque string under the bookmark key that can then be passed back in a query to get the next page of results. If any part of the selector query changes between requests, the results are undefined.&lt;br&gt;
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"bookmark": "g1AAAAB4eJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYqrpCZaWJimmKfomiemGemaWJha6CaZJ6XpmqWlGBgmJaeYmJqYgPRywPQSrSsLAKuSIMM"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As I mentioned earlier there is a maximum number of documents for the CouchDB Mango Query return result per request. So if you have result more than 250 and you want the next page result starts from 251, we can just get the current bookmark and put into our next Mango query.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "selector": {
        "status": { "$eq": "draft" }
    },
    "bookmark": "g1AAAAB4eJzLYWBgYMpgSmHgKy5JLCrJTq2MT8lPzkzJBYqrpCZaWJimmKfomiemGemaWJha6CaZJ6XpmqWlGBgmJaeYmJqYgPRywPQSrSsLAKuSIMM"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Execution Statistics Result
&lt;/h3&gt;

&lt;p&gt;As our above Mango Query &lt;em&gt;"execution_stats"&lt;/em&gt; is set to true, so CouchDB will return the execution statistic report of this mango query request.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"execution_stats": {
   "total_keys_examined":0,
   "total_docs_examined":1,
   "total_quorum_docs_examined":0,
   "results_returned":1,
   "execution_time_ms":2.253
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Warning
&lt;/h3&gt;

&lt;p&gt;This is a kindly reminder from CouchDB that we didn't create an index for this mango query. Just like any other databases. It's always recommended that to create an appropriate index when deploying in production.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"warning": "no matching index found, create an index to optimize query time"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  How to create a Mango Index?
&lt;/h2&gt;

&lt;p&gt;Since we are getting the reminder from the above example, now we can create a Mango Index to optimize the query above. This is how a Mango Index looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "index": {
        "fields": ["status"]
    },
    "ddoc" : "posts-by-status",
    "type" : "json"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;POST /{YOUR_DATABASE_NAME}/_index
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After created our index, just define the design document name of the mango index in our mango query.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "selector": {
        "status": { "$eq": "draft" }
    },
    "use_index": "posts-by-status"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you will no longer see the "warning" message from the return result.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tips: To check or debug whether your mango index has create/use properly. use /{YOUR_DATABASE_NAME}/_explain endpoint for your mango query.&lt;/p&gt;

&lt;p&gt;Another Tips: If you wish to index all fields of your document. You can define fields with empty array when creating the mango index.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  When to use Mango Query or CouchDB Views?
&lt;/h2&gt;

&lt;p&gt;For my opinion, I personally think that Mango Query is useful for ad-hoc search / sort / filtering. CouchDB Views is useful for reporting/statistics involve Sum, Count, Median or fixed recurring query. Therefore, depending on your requirement to pick which is the most suitable. But most of the time you will be using both of them within a project.&lt;/p&gt;




&lt;h2&gt;
  
  
  In Conclusion.
&lt;/h2&gt;

&lt;p&gt;This is a simple guide on using Mango Query in Apache CouchDB. Hope you find these useful. Actually there are &lt;a href="https://docs.couchdb.org/en/latest/api/database/find.html" rel="noopener noreferrer"&gt;more&lt;/a&gt; you can do with Mango Query. Check it out. &lt;/p&gt;

&lt;p&gt;Thank you for reading. 😊&lt;/p&gt;

</description>
      <category>database</category>
      <category>node</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Query in Apache CouchDB: Views</title>
      <dc:creator>Jordan Soo Yen Yih</dc:creator>
      <pubDate>Sat, 30 Oct 2021 17:05:18 +0000</pubDate>
      <link>https://dev.to/yenyih/query-in-apache-couchdb-views-4hlh</link>
      <guid>https://dev.to/yenyih/query-in-apache-couchdb-views-4hlh</guid>
      <description>&lt;p&gt;In this articles, I will talk about how to query documents in Apache CouchDB via Views.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Apache CouchDB?
&lt;/h2&gt;

&lt;p&gt;A short introduce about CouchDB first for those who don't know. Apache CouchDB is an open-source document-oriented NoSQL database, implemented in Erlang. It is very easy to use as CouchDB makes use of the ubiquitous HTTP protocol and JSON data format. Do check out their &lt;a href="https://couchdb.apache.org/" rel="noopener noreferrer"&gt;Official Website&lt;/a&gt; for more detail. 😉&lt;/p&gt;




&lt;p&gt;Alright, back to our main topic today.✌&lt;/p&gt;

&lt;p&gt;First of all, before we talk about what is view, I need to introduce 2 important things in CouchDB.&lt;/p&gt;

&lt;h2&gt;
  
  
  Query Server
&lt;/h2&gt;

&lt;p&gt;The first thing to introduce is CouchDB Query Server. What is Query Server? Based on the official documentation:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The Query server is an external process that communicates with CouchDB by JSON protocol through stdio interface and processes all design functions calls, such as JavaScript views.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;By default, CouchDB has a built-in Javascript query server running via &lt;a href="https://spidermonkey.dev/" rel="noopener noreferrer"&gt;Mozilla SpiderMonkey&lt;/a&gt;. That's mean we can define a javascript function to tell CouchDB what documents you want to query.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note: If you are not comfortable with Javascript, You can use other programming languages query server such as Python, Ruby, Clojure and etc. You can find the query server configuration &lt;a href="https://docs.couchdb.org/en/latest/config/query-servers.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Ooookay, then where to define the javascript function?🤔&lt;/p&gt;

&lt;p&gt;which is the second thing to introduce.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design Document
&lt;/h2&gt;

&lt;p&gt;Design Document is a special document within a CouchDB database. You can use design document to build indexes, validate document updates, format query results, and filter replications. Below is an example of the design document structure.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "_id": "_design/example",
    "views": {
        "view-number-one": {
            "map": "function (doc) {/* function code here */}"
        },
        "view-number-two": {
            "map": "function (doc) {/* function code here */}",
            "reduce": "function (keys, values, rereduce) {/* function code here */}"
        }
    },
    "updates": {
        "updatefun1": "function(doc,req) {/* function code here */}",
        "updatefun2": "function(doc,req) {/* function code here  */}"
    },
    "filters": {
        "filterfunction1": "function(doc, req){ /* function code here */ }"
    },
    "validate_doc_update": "function(newDoc, oldDoc, userCtx, secObj) { /* function code here */ }",
    "language": "javascript"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's us break down chunk by chunk.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. CouchDB's document ID.
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;&lt;strong&gt;Underscore id&lt;/strong&gt;&lt;/em&gt; is a reserved property key for representing the ID of the JSON document you save in the database. If the document starts with _design/ in front, meaning it is a design document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"_id": "_design/example",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. View functions
&lt;/h3&gt;

&lt;p&gt;We can define our views query logic here. Mostly driven by Javascript function as Javascript is default query server language. Later we will go more detail on the view function.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"views": {
   "view-number-one": {
      "map": "function (doc) {/* function code here */}"
   },
   "view-number-two": {
      "map": "function (doc) {/* function code here */}",
      "reduce": "function (keys, values, rereduce) {/* function code here */}"
   }
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Update functions
&lt;/h3&gt;

&lt;p&gt;Update functions are functions logic that saved in CouchDB server and then we can request to invoke to create or update a document.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"updates": {
   "updatefun1": "function(doc,req) {/* function code here */}",
   "updatefun2": "function(doc,req) {/* function code here */}"
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Filter functions
&lt;/h3&gt;

&lt;p&gt;Filter functions use to filter database changes feed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"filters": {
   "filterfunction1": "function(doc, req){ /* function code here */ }"
},
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Validate Document Update Function
&lt;/h3&gt;

&lt;p&gt;As named, you can define validation rules in this function to validate the document when you post into CouchDB.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"validate_doc_update": "function(newDoc, oldDoc, userCtx, secObj) { /* function code here */ }",
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6. Language
&lt;/h3&gt;

&lt;p&gt;Language property is telling CouchDB which programming language query server of this design document belongs to.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"language": "javascript"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I wont dive deep on &lt;em&gt;Update function&lt;/em&gt;, &lt;em&gt;Filter function&lt;/em&gt; and &lt;em&gt;Validate document function&lt;/em&gt; as our focus today is view function. If you are interested, you may leave a message below let me know😉, then I can share a post about how to use update functions too.&lt;/p&gt;




&lt;p&gt;✈Back to Views🛬&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Views?
&lt;/h2&gt;

&lt;p&gt;View in Apache CouchDB actually is a little bit similar to normal SQL database view.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A database view is a subset of a database and is based on a query that runs on one or more database tables. &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The difference is CouchDB view is based on Map Reduce.&lt;/p&gt;

&lt;p&gt;As example design document above, we can see that actually view function consists of 2 property keys (map &amp;amp; reduce), one is &lt;em&gt;&lt;strong&gt;map function&lt;/strong&gt;&lt;/em&gt;, another one is &lt;em&gt;&lt;strong&gt;reduce function&lt;/strong&gt;&lt;/em&gt;. (Reduce function is Optional)&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Map function 🔍
&lt;/h3&gt;

&lt;p&gt;Map functions accept a single document as the argument and (optionally) emit() key/value pairs that are stored in a view.&lt;/p&gt;

&lt;p&gt;Let's say we have a list of blog post documents saved in our CouchDB database.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[
  {
    _id: "c2ec3b79-d9ac-45a8-8c68-0f05cb3adfac",
    title: "Post One Title",
    content: "Post one content.",
    author: "John Doe",
    status: "submitted",
    date: "2021-10-30T14:57:05.547Z",
    type: "post"
  },
  {
    _id: "ea885d7d-7af2-4858-b7bf-6fd01bcd4544",
    title: "Post Two Title",
    content: "Post two content.",
    author: "Jane Doe",
    status: "draft",
    date: "2021-09-29T08:37:05.547Z",
    type: "post"
  },
  {
    _id: "4a2348ca-f27c-427f-a490-e29f2a64fdf2",
    title: "Post Three Title",
    content: "Post three content.",
    author: "John Doe",
    status: "submitted",
    date: "2021-08-02T05:31:05.547Z",
    type: "post"
  },
  ...
]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we want to query posts by status, we can create a javascript &lt;em&gt;map&lt;/em&gt; function as below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function (document) {
  emit(document.status, document);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxhbsadr1s8eqjtd3v7tm.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxhbsadr1s8eqjtd3v7tm.JPG" alt="Key Value Show" width="674" height="141"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the whole design document will look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "_id": "_design/posts",
    "views": {
        "byStatus": {
            "map": "function (document) { emit(document.status, document); }"
        }
    },
    "language": "javascript"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After we saved this design document into CouchDB, CouchDB will start building the view. That's it, we have create a CouchDB view successfully.🎉🥳&lt;/p&gt;

&lt;p&gt;To use the view, just send a GET method http request with the url below:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://{YOUR_COUCHDB_HOST}:5984/{YOUR_DATABASE_NAME}/_design/posts/_view/byStatus
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result: &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1re6zreifk1b6swuocv.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1re6zreifk1b6swuocv.JPG" alt="Result One" width="625" height="874"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we want to get all the posts with status "draft", then we call the http request with parameters key="draft", it will return us all the posts with status "draft" only.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://{YOUR_COUCHDB_HOST}:5984/{YOUR_DATABASE_NAME}/_design/posts/_view/byStatus?key="draft"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwrv2eom0bani2g9rrm9.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiwrv2eom0bani2g9rrm9.JPG" alt="Result Two" width="471" height="384"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let say another map function emit document by date:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function (document) {
  emit(document.date, document);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then we can query blog posts by date range.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://{YOUR_COUCHDB_HOST}:5984/{YOUR_DATABASE_NAME}/_design/posts/_view/byDate?startkey=""&amp;amp;endkey="2021-09-29\uffff"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosm3wtmnhym1avx9pi26.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosm3wtmnhym1avx9pi26.JPG" alt="Result Date Range" width="511" height="632"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As query above, I defined a start date via &lt;em&gt;startkey&lt;/em&gt; and end date via &lt;em&gt;endkey&lt;/em&gt; , then CouchDB will return we the posts within the startkey and endkey. However my startkey is empty string, meaning that I don't care about start date, just give me the first post document until the date of the endkey.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Tips: If you want to reverse the return result, you can just add a parameter "descending=true"&lt;/p&gt;
&lt;/blockquote&gt;


&lt;h3&gt;
  
  
  2. Reduce/Rereduce ✂
&lt;/h3&gt;

&lt;p&gt;Reduce function is optional to a view, it is based on the map function result then you can perform SUM, COUNT or custom logic with to filter or derive into any desire result.&lt;/p&gt;

&lt;p&gt;Let's say we have a map result shows (month, expenses):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function (document) {
  emit(document.month, document.expenses);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example Result:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqrchmdb40fbs792lh62.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqrchmdb40fbs792lh62.JPG" alt="Result Month" width="555" height="868"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If we want to get february expenses only, then we will put a parameter &lt;em&gt;&lt;strong&gt;key="february"&lt;/strong&gt;&lt;/em&gt;, then it will return us february expenses only. &lt;br&gt;
Based on the map result, we can add a reduce function to help us to sum the february expenses amount.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function(keys, values, rereduce) {
  return sum(values);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Result for &lt;em&gt;&lt;strong&gt;key="february"&lt;/strong&gt;&lt;/em&gt; after reduce :&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp2uihbjq0o3naih9wuvv.JPG" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp2uihbjq0o3naih9wuvv.JPG" alt="Result Reduce" width="300" height="204"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it. We can instantly get the sum result no matter how many documents you have in the database. This is the power of Map Reduce. You can even rereduce, meaning perform second time reduce logic based on the first reduce result. For more detail, you may check out the official documentation &lt;a href="https://docs.couchdb.org/en/latest/ddocs/views/intro.html" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  In Conclusion
&lt;/h2&gt;

&lt;p&gt;CouchDB views is very powerful, flexible and super fast to query a result like Hadoop. However, CouchDB only supports one layer map reduce derivation. If you do not understand what is Map Reduce, you may check out this &lt;a href="https://www.youtube.com/watch?v=43fqzaSH0CQ&amp;amp;ab_channel=internet-class" rel="noopener noreferrer"&gt;Youtube video&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thank you for your reading.😊&lt;/p&gt;

</description>
      <category>database</category>
      <category>node</category>
      <category>beginners</category>
    </item>
  </channel>
</rss>
