今日已更新 334 条资讯 | 累计 37239 条内容
关于我们

标签:#mongodb

找到 16 篇相关文章

AI 资讯

A New Way to Build Aggregation Pipelines in Go

This article was written by Lin Borland Aggregation pipelines are one of the most powerful tools in MongoDB. They let you filter, reshape, compute, and group documents in a single query. In practice, the aggregation framework feels almost like a language of its own. With its combination of stages, expressions, and operators, you can describe everything from straightforward filtering to sophisticated transformation logic. This expressive power is what makes aggregation pipelines so useful, and is also why they have a learning curve associated with them. If you’ve worked with MongoDB in Go, you may know that the existing syntax for writing pipelines in Go can be cumbersome to work with. This is especially true when a pipeline includes several stages, repeated computed logic, or deeply nested expressions. In these cases, both readability and writability may begin to suffer. There’s a need for a more Go-native way to build aggregation pipelines. This is why we’re introducing a new approach: an experimental aggregation builder in Go. In this article, we’ll compare the traditional and new approaches, then go through an example. The traditional BSON-based approach Today, if you want to build an aggregation pipeline with the Go driver, you typically do it with bson.D, bson.A, and mongo.Pipeline. While this approach is flexible, it can be hard to spot small mistakes. Let’s use a simple example from the sample_mflix.movies collection. Suppose we want to find movies released after the year 2000. Here’s a pipeline that demonstrates how easy it can be to get the shape wrong: mongo . Pipeline { bson . D {{ Key : "$match" , Value : bson . E { Key : "$gte" , Value : bson . E { Key : "$year" , Value : 2000 }}}}} At a glance, the mistake might not be obvious. The document is valid BSON, but the pipeline uses “bson.E” instead of “bson.D” for some values, resulting in a pipeline that returns zero results. If we try to fix the nesting, we can still end up with a pipeline that is structu

2026-08-25 原文 →
AI 资讯

From MySQL to MongoDB in Spring Boot — Everything That Changed in My Code

In my last post I wrote about an error that cost me a full evening: my pom.xml had the MongoDB starter, but my code was still full of JPA annotations. The compiler kept saying cannot find symbol: class Entity . That post was about the error. This post is about the fix — every single line I had to change to move my Task Manager project from MySQL to MongoDB. If you are planning the same switch, this is the checklist I wish I had. 1. The dependency Before (MySQL + JPA): <dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-starter-data-jpa </artifactId> </dependency> <dependency> <groupId> com.mysql </groupId> <artifactId> mysql-connector-j </artifactId> <scope> runtime </scope> </dependency> After (MongoDB): <dependency> <groupId> org.springframework.boot </groupId> <artifactId> spring-boot-starter-data-mongodb </artifactId> </dependency> One starter replaces two dependencies. And this is exactly where my problem started — I added the new one but never removed the old one, so half my code still compiled and half did not. Remove the JPA starter completely. If you leave it in, the jakarta.persistence annotations still resolve, and you will not notice you are mixing two worlds until something breaks at runtime. 2. application.properties Before: spring.datasource.url = jdbc:mysql://localhost:3306/taskmanager spring.datasource.username = root spring.datasource.password = yourpassword spring.jpa.hibernate.ddl-auto = update spring.jpa.show-sql = true After: spring.data.mongodb.uri = mongodb://localhost:27017/taskmanager Five lines became one. No ddl-auto because MongoDB has no schema to create. No dialect because there is no SQL being generated. The database and the collection are created automatically the first time you insert a document. 3. The model class This is where most of the work was. Here is my actual Task class after the migration: package com.taskmanager.task_manager ; import com.fasterxml.jackson.annotation.JsonIgnore ; import org.

2026-08-19 原文 →
AI 资讯

Mongodb Partitioning

At Whoz , we build a SaaS platform that helps professional services companies manage their talent staffing. At the heart of our product lies a concept called a worklog — a record of time spent by a user on a given activity. Every consultant, every day, on every project, generates worklogs. It sounds simple. And for years, it was. Then the numbers caught up with us. The Problem: A Collection That Never Stops Growing Our worklog MongoDB collection had reached 530 million documents , representing just over 32 GB of data. And the growth rate was accelerating — not just because we were onboarding more clients, but because users were increasingly splitting their activity into finer-grained entries, generating more worklogs per person per day than ever before. A worklog document looks roughly like this: { "date" : "2024-03-15" , "talentId" : "abc123" , "workspaceId" : "ws456" , "duration" : 0.5 , "activityType" : "TASK" , "taskId" : "task789" } Simple enough. But at 530 million of them, even the most routine operations become painful: Backup : nearly 1 hour Restore : up to 4 hours Schema migrations : we hadn't dared run one at full scale yet — and that alone was a warning sign Every year, the collection grows faster than the year before. The backup and restore windows were becoming operationally risky. We needed to act. Exploring Our Options We identified three potential approaches before settling on a solution. Option 1 — MongoDB Sharding Sharding is MongoDB's native horizontal scaling mechanism. It distributes a collection across multiple shards, each backed by its own replica set. On paper, it looked like a match. In practice, we ran into a fundamental mismatch with our actual needs. Our core issue wasn't query throughput — worklogs from three years ago are rarely queried, and when they are, performance expectations are low. Our issue was operational overhead : backup time, restore time, and the cost of running large batch operations over the full dataset. Sharding woul

2026-08-18 原文 →
AI 资讯

Building a Restaurant Reservation System with Node.js, Express & MongoDB - A Beginner's Guide

Building a Restaurant Reservation System with Node.js, Express & MongoDB - A Beginner's Guide Tags: #nodejs #express #mongodb #webdevelopment #tutorial #beginner Introduction Hey everyone! 👋 This is my first Dev.to post, and I'm excited to share what I've been learning. As a 5th-semester CS student, I've been diving deep into full-stack web development, and today I want to walk you through building a Restaurant Reservation System – a real project I built that taught me so much about backend architecture and database design. If you're just starting with Node.js, Express, and MongoDB, this post is for you! What We'll Build A simple but functional restaurant reservation system where: Users can browse available time slots Users can book a table for a specific date and time Admin can manage reservations Weekly scheduling (Monday-Sunday) 2-hour time slots Tech Stack: Backend: Node.js + Express Database: MongoDB Frontend: React + Tailwind CSS (we'll focus on backend in this post) Prerequisites Before we start, make sure you have: Node.js installed MongoDB running locally or MongoDB Atlas account Basic JavaScript knowledge VS Code or any code editor Project Setup 1. Initialize the Project mkdir restaurant-reservation-system cd restaurant-reservation-system npm init -y 2. Install Dependencies npm install express mongoose cors dotenv npm install nodemon --save-dev 3. Create Project Structure restaurant-reservation-system/ ├── models/ │ └── Reservation.js ├── routes/ │ └── reservations.js ├── config/ │ └── db.js ├── .env ├── server.js └── package.json Step 1: Set Up MongoDB Connection config/db.js const mongoose = require ( ' mongoose ' ); const connectDB = async () => { try { await mongoose . connect ( process . env . MONGODB_URI ); console . log ( ' MongoDB connected successfully ' ); } catch ( error ) { console . log ( ' MongoDB connection failed: ' , error ); process . exit ( 1 ); } }; module . exports = connectDB ; Step 2: Create Reservation Model models/Reservation.js co

2026-08-15 原文 →
AI 资讯

A backup you haven't restored isn't a backup

Migrating from MongoDB Atlas to a self-hosted replica set bought us control and cut our bill. It also quietly removed something we had stopped thinking about: Atlas had been taking continuous backups for us the entire time. After the migration, production data for Prochesta lived in /var/db/mongo on a single VPS. No snapshots. No off-box copy. A rm -rf , a bad migration script, or a dead disk would have been the end of it. We had written "backups" as a follow-up task in the migration spec, which is the engineering equivalent of a sticky note on a bank vault. The requirement we actually cared about was narrower than "back up the database". Most real-world data loss at our scale isn't hardware failure — it's a deploy that writes garbage, or someone running an update without a filter. Recovering to last night doesn't help when the damage happened at 14:20 and you noticed at 14:50. We needed to recover to an arbitrary moment , not to a nightly snapshot. The constraint nobody mentions: Community has no $backupCursor We chose Percona Backup for MongoDB (PBM), and immediately hit the limitation that shapes every decision downstream. PBM offers physical backups — fast file-level copies that restore in minutes and barely touch the running server. They work by opening a backup cursor via the $backupCursor aggregation stage. That stage exists in Percona Server for MongoDB and in MongoDB Enterprise. It does not exist in MongoDB Community, which is what the official mongo:8.0 image ships. So on Community, PBM gives you logical backups only: every document read out through mongod , compressed, and shipped off-box. Two consequences, both accepted deliberately rather than discovered later: Backups cost CPU on the primary — and with a single-member replica set there's no secondary to offload the read to. Restores insert documents and rebuild indexes, so restore time grows with data size much faster than backup time does. At our current size that's minutes, not hours. It's also the t

2026-08-10 原文 →
AI 资讯

Building a Bulletproof Comment Reply System in Node.js & MongoDB 🚀

When building a nested reply system, most developers worry about deep tree complexity or messy data structures. For Vlox , I took a different approach: keeping things flat, fast, and secure by reusing a single Mongoose schema with smart atomic limits. Here is a deep dive into how I engineered a production-ready, race-condition-safe reply mechanism using MongoDB transactions, strict type sanitization, and automated limits. How It Works 🛠️ User Action: A user clicks the reply icon and submits their reply. The Payload: Vlox's system sends 3 fields via the endpoint /api/v1/reply/comment/post/:id : id : The post ID (passed as a URL parameter). rootCommentId : The ID of the root comment being replied to. reply : The raw text entered by the user. Sanitization & Validation: The incoming reply is instantly converted to a trimmed string. It then passes through two critical validation checks: Existence Check: The reply must exist. (If a malicious actor sends a payload without a body, the string literally evaluates to "undefined" and gets blocked). Length Limit: The reply must be under 201 characters, enforcing the standard comment limit. Atomic Transactions: If the validation checks pass, the system initiates a Mongoose transaction to execute the following steps safely: Permission Check: It verifies if the user has permission to reply by checking the post's status via await schemas.Posts.findOne(hotQueries.find_user_post(id, req.session.userId)); . Creation: If permissions are valid, it creates a new reply. (Fun fact: It reuses the exact same schema as standard comments!) The Reply Schema Structure: The reply object functions just like a normal comment, with two distinct exceptions: It does not contain a repliesCount field. It includes an extra rootId field, which explicitly points to the ID of the root comment being replied to. Concurrency & Caps: To guarantee that a single comment never receives more than 10 replies while simultaneously incrementing the counter, the system r

2026-08-09 原文 →
AI 资讯

Building the foundation Claudius runs on

This tutorial was written by Néstor Daza . This is the third article in a series about building Claudius , my own Claude-based chatbot ( Github ). The previous article discussed the MongoDB data model to use for the app. The previous article decided the shape of the data. None of it matters until the app around it is working, and getting it there is the unglamorous half of this phase. It comes down to three things: an identity system the client cannot tamper with, proof that Claudius can reach the two services it depends on, and the deployment realities that decide whether any of it runs at all. This is the boring work that quietly decides whether a project survives contact with production. Identity: the client never gets a vote Any Google account on Earth can sign into Claudius safely because a user's role is never something the client sends. It is decided on the server every time. One piece of this lives outside the code. The Google provider needs an OAuth (Open Authorization) client that you register once in the Google Cloud Console, and the client identifier and secret from that registration are set in corresponding env variables. These setup steps live in the Auth.js and Google documentation, so I am not repeating them here. Sign-in runs on Auth.js v5 with the Google provider and the MongoDB adapter. There are three roles, admin, member, and guest, and they resolve in exactly one place on the server, with a clear precedence: export async function resolveRole ( email : string | null | undefined ): Promise < Role > { if ( ! email ) return " guest " ; const normalized = email . toLowerCase (); if ( normalized === env . ADMIN_EMAIL . toLowerCase ()) return " admin " ; const settings = await settingsCol (); const allowlist = await settings . findOne ({ _id : " allowlist " }); if ( allowlist && " emails " in allowlist ) { const allowed = allowlist . emails . some (( e ) => e . toLowerCase () === normalized ); if ( allowed ) return " member " ; } return " guest " ; }

2026-08-04 原文 →
AI 资讯

I Built a Blood Donation Management System with the MERN Stack

Every year, thousands of people struggle to find blood donors during emergencies. I wanted to build something that could simplify that process while improving my full-stack development skills. So I built a Blood Donation Management System using the MERN Stack. The goal was simple: create a platform where donors, recipients, and volunteers can connect efficiently through a modern web application. In this article, I'll share the architecture, key features, and the lessons I learned while building it. Tech Stack : Frontend React.js React Router Tailwind CSS Axios Backend Node.js Express.js Database MongoDB Mongoose Authentication JWT bcrypt Deployment Vercel (Frontend) Render (Backend) The Problem Finding blood donors during emergencies is often difficult because information is scattered across social media and messaging apps. I wanted to build a centralized platform where users could: Register as blood donors Search donors by blood group and location Request blood Manage donation information Keep donor data organized 🏗️Project Architecture Client (React) │ REST API │ Node.js + Express │ ├── Authentication ├── Donor Management ├── Blood Requests ├── User Dashboard └── Admin Panel │ MongoDB Keeping the frontend and backend separated made the project easier to maintain and scale. Key Features Secure user authentication Role-based dashboard Blood donor registration Search donors by blood group Blood request management Responsive UI Protected routes RESTful API Project Structure client/ ├── components/ ├── pages/ ├── hooks/ ├── layouts/ └── routes/ server/ ├── controllers/ ├── middleware/ ├── models/ ├── routes/ ├── utils/ └── config/ Organizing the project into separate folders helped keep the codebase clean and easier to extend. Authentication Flow Authentication was implemented using JWT and bcrypt. The basic flow looks like this: Register ↓ Password Hashing ↓ MongoDB ↓ Login ↓ JWT Token ↓ Protected Routes This keeps user data secure while allowing authenticated access

2026-07-30 原文 →
AI 资讯

How to Import JSON into MongoDB and Export to CSV with Data Masking

Every morning, an online store receives the previous day’s orders from a marketplace partner. The file comes in JSON format. The company needs to add those orders to its main MongoDB orders collection. The sales manager also needs a CSV report that can be opened in Excel. That sounds like a small task. Import the file, copy the documents, export the report. But in practice, a few things can break the process. A date can be imported as a string. A field can have the wrong name. One batch may use total , while the main collection uses totalAmount . A temporary collection can keep old records and trigger duplicate key errors. A CSV export can create null values because the mapping points to fields that do not exist. And then there is customer data. The manager may need the sales numbers, but they probably do not need real customer names or internal customer IDs. This article walks through a real daily workflow: Import marketplace JSON ↓ Store the batch in a temporary MongoDB collection ↓ Copy the orders into the main orders collection ↓ Mask customer fields during export ↓ Create a CSV report The goal is not just to move data from JSON to CSV. The goal is to make the process repeatable, easier to check, and safer to share. The workflow The workflow has three jobs: Import Yesterday Orders ↓ Add Orders to Main ↓ Export Daily Sales Report The important part is the parent relationship between the jobs. Add Orders to Main depends on Import Yesterday Orders , so it only runs after the JSON file is imported successfully. Export Daily Sales Report depends on Add Orders to Main , so the CSV is created only after the main orders collection has been updated. This prevents the report from being generated when data is missing or incomplete. The incoming JSON file The partner sends a file with yesterday’s completed orders. A single order looks like this: { "orderId" : "ORD-2026-07-201" , "customerId" : "CUST-1003" , "customerName" : "Sofia Rossi" , "orderDate" : "2026-07-21T08:20:00

2026-07-23 原文 →
AI 资讯

7 MongoDB Query Mistakes That Return the Wrong Results

MongoDB queries look simple. You type a field, give it a value, hit run, and you get your data back. But just because a query runs without throwing an error doesn't mean it worked right. Sometimes you get a blank screen. Sometimes you get way too many records. Other times, the data looks fine at first glance, but it doesn't actually match what you asked for. Most of these slip-ups happen for one basic reason: the query structure doesn't match the way the data actually sits in the database. To show you what we mean, we’ll use a clinic database with a collection called visits . Here is what a typical document looks like: JSON { "_id": "6871b6f9c3f1d1a4c2a10001", "status": "completed", "visitDate": "2026-07-01T09:30:00.000Z", "patient": { "name": "Anna Keller", "age": 34 }, "doctor": { "name": "Dr. James Carter", "specialty": "Cardiology" }, "symptoms": ["cough", "fever"], "prescriptions": [ { "name": "Ibuprofen", "active": false }, { "name": "Paracetamol", "active": true } ], "invoice": { "paid": true, "method": "card", "total": 250 } } You can run these examples right in the VisuaLeaf MongoDB Shell . Using visual tools makes a big difference because you can see exactly what MongoDB is returning in real time. 1. Forgetting the Curly Braces This is just a quick typo, but it breaks things right away. The Mistake: db . visits . find ( status : " completed " ) The Correct Query The find() tool always expects an object. Even if you are only looking for one specific thing, you still need to wrap that condition in curly braces {} . 2. Treating $or Like a Regular Object This one trips a lot of people up because the broken version looks like it should work. The Mistake: db.visits.find({ $or: { status: "completed", "invoice.paid": false } }) What is wrong: $or expects an array of conditions, but this query gives it one object. The error will usually be something like: MongoServerError: $or must be an array The Correct Query The first query is wrong because $or needs an array, n

2026-07-14 原文 →
AI 资讯

Building a Four-Tier Parallel RAG Pipeline with Gemini

The Problem When building BotForge, our AI no-code chatbot platform, we needed a retrieval system that could handle messy, real-world user queries — typos, partial phrases, semantically similar-but-differently-worded questions. A naive vector search alone wasn't good enough. It's powerful but brittle to out-of-vocabulary terms and exact keyword lookups. The Solution: Four-Tier Parallel Retrieval We ran four retrieval strategies simultaneously using Promise.all\ , then merged results with a weighted scoring function. \ javascript const [semanticResults, textResults, regexResults, fuzzyResults] = await Promise.all([ semanticSearch(query, embeddings), // weight 1.8x mongoFullTextSearch(query), // weight 1.5x regexKeywordSearch(query), // weight 1.0x fuzzyPerWordMatch(query), // weight 0.6x ]) \ \ Tier 1: Semantic Search (1.8× weight) Using Gemini gemini-embedding-2\ to produce 3072-dimensional vectors , we compute cosine similarity against stored document embeddings. This catches meaning — "how do I reset my login?" matches "account recovery options" even with no shared words. Tier 2: MongoDB Full-Text Search (1.5× weight) A native MongoDB Atlas text index for fast, exact keyword hits. Great for technical terms, product names, and precise phrases. Tier 3: Regex Keyword Matching (1.0× weight) Each significant word in the query is compiled to a case-insensitive regex. Catches partial matches and hyphenated variants. Tier 4: Fuzzy Per-Word Matching (0.6× weight) Levenshtein distance matching per query word — handles typos and misspellings like "configuraton" → "configuration". Weighted Score Merging Each result carries a base score from its retrieval strategy. We deduplicate by chunk ID, sum scores across strategies, and sort descending: \ javascript function mergeResults(tiers, weights) { const scoreMap = new Map() tiers.forEach((results, i) => { results.forEach(({ id, score, chunk }) => { const weighted = score * weights[i] scoreMap.set(id, { chunk, total: (scoreMap.get

2026-07-07 原文 →
AI 资讯

No messages table! The data model behind my own Claude-based chatbot

This tutorial was written by Néstor Daza . This is the second article in a series about building Claudius , my own Claude-based chatbot ( Github ). The prologue made the case for building it, and for choosing MongoDB as its foundation. Open the conversations collection in Claudius’ database and you find the usual fields of a thread header but nothing else: a userId , a title , some timestamps , and so on, but no array of messages, no messages collection sitting beside it either! The text of every conversation lives somewhere else entirely, in the LangGraph checkpointer, which I wire up later in this series. This absence is a modeling decision, and how I came up with the database schema for my chatbot is the theme of this article. If you come from a relational background, you're used to modeling the data first when designing a database. For a project like this, you would start by finding the entities and normalizing them, and the final schema would come out of the data's structure: a conversations table and a messages table with a foreign key between them, because that is what the data looks like. Document modeling runs the other way. You start from how the application reads and writes, and the shape of the document follows the access patterns. Claudius never reads conversation messages without the agent's full working state wrapped around them, and that state is persisted using the LangGraph checkpointer. A separate messages table would add nothing, since the app would always have to join it back to that state on every read. The access pattern says the messages belong with the agent state, so that is where they go, and conversations are left as the lightweight header the list view actually needs. That inversion, modeling around use rather than around the data, runs through everything below. Schema-flexible is not schemaless This is the misconception lots of people often carry, and it is worth killing on the way in. A document database does not mean no schema; it mea

2026-07-02 原文 →
AI 资讯

MongoDB Indexes Finally Clicked for Me: Understanding Indexes, Compound Indexes & the Prefix Rule 🚀

While working on a MERN project, I came across these indexes: transactionSchema . index ({ user : 1 , date : - 1 }); transactionSchema . index ({ user : 1 , type : - 1 }); transactionSchema . index ({ user : 1 , category : - 1 }); My first reaction was: "Why are we creating 3 different indexes for the same schema? Isn't one index enough?" At that time, my understanding was: "Indexes help MongoDB find records faster." Which is true, but it wasn't enough to explain why multiple indexes existed for the same collection. That simple doubt led me down a rabbit hole of learning about indexes, compound indexes, how MongoDB stores them, and the famous Prefix Rule. Here's what I learned. What is an Index? Imagine a collection with millions of transactions. db . transactions . find ({ user : " Aarthi " }); Without an index, MongoDB may need to inspect every document until it finds the matching records. This is called a Collection Scan . Think of it like searching for a chapter in a book without a table of contents. You'd have to flip through page after page until you find it. An index works like a book's table of contents. Instead of scanning every document, MongoDB can jump directly to the relevant records. Example: db . transactions . createIndex ({ user : 1 }); Now MongoDB can quickly locate all transactions belonging to a specific user. What is a Compound Index? A compound index contains multiple fields. Example: db . transactions . createIndex ({ user : 1 , date : - 1 }); This means MongoDB organizes the index by: user └── date Conceptually, it looks something like: Aarthi 2025-08-10 2025-08-09 2025-08-08 John 2025-08-10 2025-08-05 The data is first grouped by user , and within each user, it is ordered by date . Now queries like: db . transactions . find ({ user : " Aarthi " }). sort ({ date : - 1 }); become very efficient. MongoDB can jump directly to Aarthi's records and retrieve them in date order. The Prefix Rule: The Concept That Finally Made It Click Consider this i

2026-06-24 原文 →
AI 资讯

Day 71 of Learning MERN Stack

Hello Dev Community! 👋 It is officially Day 71 of my unbroken 100-day full-stack engineering run! After mastering polymorphic multi-part storage configurations yesterday, today I successfully crossed into core transactional operations: Engineering a High-Fidelity "Confirm and Pay" Checkout View and Wiring Database Inbound Array Modifications! In real-world booking platforms, processing a successful transaction requires more than updating an absolute view; you have to link documents relationally across collections. Today, I wired that entire execution pipeline together! 🧠 What I Handled on Day 71 (Checkout Engineering & Target Mutations) As displayed across my latest system files in "Screenshot (164).png" and "Screenshot (165).jpg" , handling payments runs through structured backend steps: 1. High-Fidelity Checkout Component ( /reserve ) I built out the detailed split-pane verification interface visible in "Screenshot (164).png" . The layout captures target trip date selections, total guests parameter caps, card input structures, and computes subtotal ledgers dynamically: Base Compute: $9000 x 5 nights = $45000 . Transactional Upgrades: Appending structured service charges ( $85 ) and local tax calculations ( $42 ) to update the final sum directly to $45127 . 2. Live Document Array Mutators (MongoDB User List Insertion) The most crucial logic happens when the user clicks the primary validation trigger labeled Confirm and pay : The inbound route controller extracts the targeted property identity token ( home._id ) via an embedded hidden input container. Instead of running isolation updates, it issues an atomized update operation straight into our MongoDB user records array (e.g., using Mongoose operators like $push or tracking active profiles inside our custom data state loops). This appends the exact property listing target ID directly into the user's booking history array database matrix! 🛠️ View Markup Code Integration View As showcased in my VS Code script structu

2026-06-23 原文 →