Explore Developer Center's New Chatbot! MongoDB AI Chatbot can be accessed at the top of your navigation to answer all your MongoDB questions.

MongoDB Developer
MongoDB
plus
Sign in to follow topics
MongoDB Developer Centerchevron-right
Developer Topicschevron-right
Productschevron-right
MongoDBchevron-right

Wordle Solving Using MongoDB Query API Operators

Erik Hatcher4 min read • Published Feb 01, 2023 • Updated Feb 01, 2023
MongoDBAggregation Framework
Facebook Icontwitter iconlinkedin icon
M O N G O
Rate this article
star-empty
star-empty
star-empty
star-empty
star-empty
This article details one of my MongoDB Atlas learning journeys. I joined MongoDB in the fall of 2022 as a Developer Advocate for Atlas Search. With a couple of decades of Lucene experience, I know search, but I had little experience with MongoDB itself. As part of my initiation, I needed to learn the MongoDB Query API, and coupled my learning with my Wordle interest.

Game on: Introduction to Wordle

The online game Wordle took the world by storm in 2022. For many, including myself, Wordle has become a part of the daily routine. If you’re not familiar with Wordle, let me first apologize for introducing you to your next favorite time sink. The Wordle word guessing game gives you six chances to guess the five-letter word of the day. After a guess, each letter of the guessed word is marked with clues indicating how well it matches the answer. Let’s jump right into an example, with our first guess being the word ZESTY. Wordle gives us these hints after that guess:
ZESTY
The hints tell us that the letter E is in the goal word though not in the second position and that the letters Z, S, T, and Y are not in the solution in any position. Our next guess factors in these clues, giving us more information about the answer:
ZESTY BREAD
Do you know the answer at this point? Before we reveal it, let’s learn some MongoDB and build a tool to help us choose possible solutions given the hints we know.

Modeling the data as BSON in MongoDB

We can easily use the forever free tier of hosted MongoDB, called Atlas. To play along, visit the Atlas homepage and create a new account or log in to your existing one.
Once you have an Atlas account, create a database to contain a collection of words. All of the possible words that can be guessed or used as daily answers are built into the source code of the single page Wordle app itself. These words have been extracted into a list that we can quickly ingest into our Atlas collection.
I created a repository for the data and code here. The README shows how to import the word list into your Atlas collection so you can play along.
The query operations needed are:
  • Find words that have a specific letter in an exact position.
  • Find words that do not contain any of a set of letters.
  • Find words that contain a set of specified letters, but not in any known positions.
In order to accommodate these types of criteria, a word document looks like this, using the word MONGO to illustrate:
1{
2 "_id":"MONGO",
3 "letter1":"M",
4 "letter2":"O",
5 "letter3":"N",
6 "letter4":"G",
7 "letter5":"O",
8 "letters":["M","O","N","G"]
9}

Finding the matches with the MongoDB Query API

Each word is its own document and structured to facilitate the types of queries needed. I come from a background of full-text search where it makes sense to break down documents into the atomic findable units for clean query-ability and performance. There are, no doubt, other ways to implement the document structure and query patterns for this challenge, but bear with me while we learn how to use MongoDB Query API with this particular structure. Each letter position of the word has its own field, so we can query for exact matches. There is also a catch-all field containing an array of all unique characters in the word so queries do not have to be necessarily concerned with positions.
Let’s build up the MongoDB Query API to find words that match the hints from our initial guess. First, what words do not contain Z, S, T, or Y? Using MongoDB Query API query operators in a .find() API call, we can use the $nin (not in) operator as follows:
1{
2 "letters":{
3 "$nin":["Z","S","T","Y"]
4 }
5}
Independently, a .find() for all words that have a letter E but not in the second position looks like this, using the $all operator as there could be potentially multiple letters we know are in the solution but not which position they are in:
1{
2 "letters":{
3 "$all":["E"]
4 },
5 "letter2":{"$nin":["E"]}
6}
To find the possible solutions, we combine all criteria for all the hints. After our ZESTY guess, the full .find() criteria is:
1{
2 "letters":{
3 "$nin":["Z","S","T","Y"],
4 "$all":["E"]
5 },
6 "letter2":{"$nin":["E"]}
7}
Out of the universe of all 2,309 words, there are 394 words possible after our first guess.
Now on to our second guess, BREAD, which gave us several other tidbits of information about the answer. We now know that the answer also does not contain the letters B or D, so we add that to our letters field $nin clause. We also know the answer has an R and A somewhere, but not in the positions we initially guessed. And we have now know the third letter is an E, which is matched using the $eq operator. Combining all of this information from both of our guesses, ZESTY and BREAD, we end up with this criteria:
1{
2 "letters":{
3 "$nin":["Z","S","T","Y","B","D"],
4 "$all":["E","R","A"]
5 },
6 "letter2":{"$nin":["E","R"]},
7 "letter3":{"$eq":"E"},
8 "letter4":{"$nin":["A"]}
9}
Has the answer revealed itself yet to you? If not, go ahead and import the word list into your Atlas cluster and run the aggregation.
It’s tedious to accumulate all of the hints into .find() criteria manually, and duplicate letters in the answer can present a challenge when translating the color-coded hints to MongoDB Query API, so I wrote a bit of Ruby code to handle the details. From the command-line, using this code, the possible words after our first guess looks like this….
1$ ruby word_guesser.rb "ZESTY x~xxx"
2{"letters":{"$nin":["Z","S","T","Y"],"$all":["E"]},"letter2":{"$nin":["E"]}}
3ABIDE
4ABLED
5ABODE
6ABOVE
7.
8.
9.
10WOVEN
11WREAK
12WRECK
13394
The output of running word_guesser.rb consists first of the MongoDB Query API generated, followed by all of the possible matching words given the hints provided, ending with the number of words listed. The command-line arguments to the word guessing script are one or more quoted strings consisting of the guessed word and a representation of the hints provided from that word where x is a greyed out letter, ~ is a yellow letter, and ^ is a green letter. It’s up to the human solver to pick one of the listed words to try for the next guess. After our second guess, the command and output are:
1$ ruby word_guesser.rb "ZESTY x~xxx" "BREAD x~^~x"
2{"letters":{"$nin":["Z","S","T","Y","B","D"],"$all":["E","R","A"]},"letter2":{"$nin":["E","R"]},"letter3":{"$eq":"E"},"letter4":{"$nin":["A"]}}
3OPERA
41
Voila, solved! Only one possible word after our second guess.
OPERA
In summary, this fun exercise allowed me to learn MongoDB’s Query API operators, specifically $all, $eq, and $nin operators for this challenge.
To learn more about the MongoDB Query API, check out these resources:

Facebook Icontwitter iconlinkedin icon
Rate this article
star-empty
star-empty
star-empty
star-empty
star-empty
Related
Quickstart

MongoDB and Node.js Tutorial - CRUD Operations


Aug 22, 2023 | 17 min read
Tutorial

Getting Started With MongoDB and Amazon Q Developer generative AI–powered coding assistant


Sep 25, 2024 | 3 min read
News & Announcements

Supercharging Time Series Collections: Key Enhancements in MongoDB 8.0 with Block Processing


Dec 09, 2024 | 4 min read
Article

3 Things to Know When You Switch from SQL to MongoDB


Oct 01, 2024 | 6 min read
Table of Contents