JavaScript everywhere Chapter 5 database (^_ ^)

Time:2021-2-5

JavaScript everywhere Chapter 5 database (^_ ^)

Write at the front

Hello everyone, I’m Mao Xiaoyou, a front-end development engineer. I’m translating an English technical book.

In order to improve our reading experience, the structure and content of the sentence are slightly adjusted. If you find any flaws in this article, or you have any comments or suggestions, you can leave a message in the comments area, or add my wechat:code_maomaoWelcome to communicate and study with each other.

(σ゚∀゚)σ..:*Ouch, not bad

Translation|《JavaScript Everywhere》The third5Chapter database (^_ ^)

Chapter 5 database

When I was a child, I was obsessed with collecting all kinds of sports cards. A large part of the process of collecting cards is sorting them out. I put the star players in a box. There is a whole box for basketball superstar Michael Jordan(Michael Jordan)The rest of the cards are classified by sport or by team. This organization method enables me to store cards safely and easily find the cards I am looking for at any given time. I feel like I don’t know much about it, but a storage system like this is actually equivalent to a database. The core of a database is to allow us to store information and retrieve it later.

It’s just beginningWebWhen developing, I found databases daunting. I’ve seen a lot about running databases and entering obscure informationSQLCommand description, which feels like an additional abstraction, I can’t handle. Fortunately, I finally got over the hurdle and was no longer held backSQLTable joins are intimidated, so if you’re still hesitating, I hope you know you can browse the world of databases.

In this book, we will useMongoDBAs our preferred database. The reason why I chooseMongoBecause it isNode.jsA popular choice in the ecosystem and a great database for anyone to get started with.MongoStore our data in aJavaScriptObject. This means that we will be able to do anythingJavaScriptDevelopers are familiar with the format of writing and retrieving information. However, if you have a favorite database (e.gPostgreSQL)Then the topics covered in this book can be transferred to any type of system with very little work.

in useMongoBefore that, we need to make sure thatMongoDBThe server is running locally. This is required throughout the development process. For this purpose, please follow section1Chapter on the system.

Introduction to mongodb

functionMongo, let’s explore how to use itMongo ShellFrom the terminal directly withMongoInteraction.

First, open it by typingMongoDB shell

mongoCommand:

$ mongo

After running this command, you should see theMongoDB ShellLocal server connection information, as well as some other information printed to the terminal. Now, we can communicate with each other directly from the terminal applicationMongoDBInteract. We can use the command to create a database.

Let’s create one calledlearningDatabase for:

$ use learning

In the card collection at the beginning of this chapter, I put the cards in different boxes.MongoDBBrings the same concept, called set.

Collections are our way of putting together similar documents. For example, a blog application might have a collection of articles, a collection of users, and a third collection of comments. If the set andJavaScriptObject, it will be a top-level object, and the document will be a single object in it. We can visualize it like this:

collection: {
  document: {},
  document: {},
  document: {}.
  ...
}

With this information in hand, let’s create a document in the collection of the learning database. We will create a collection of pizzas in which to store documents of the pizzas type. stayMongoDB shellEnter the following in the

$ db.pizza.save({ type: "Cheese" })

If successful, we should see a return result:

WriteResult({ "nInserted" : 1 })

We can also write multiple entries to the database at one time:

$ db.pizza.save([{type: "Veggie"}, {type: "Olive"}])

Now that we have written some documents to the database, let’s retrieve them. For this, we will useMongoDBOffindmethod. To view all the documents in the collection, run the find with null arguments command:

$ db.pizza.find()

Now, we should see all three entries in the database. In addition to storing data,MongoDBEach entry is also automatically assigned a uniqueID. The results should be as follows:

{ "_id" : ObjectId("5c7528b223ab40938c7dc536"), "type" : "Cheese" }
{ "_id" : ObjectId("5c7529fa23ab40938c7dc53e"), "type" : "Veggie" }
{ "_id" : ObjectId("5c7529fa23ab40938c7dc53f"), "type" : "Olive" }

We can also use attribute values andMongoAllocatedIDTo find a single document:

$ db.pizza.find({ type: "Cheese" })
$ db.pizza.find({ _id: ObjectId("A DOCUMENT ID HERE") })

Not only do we want to be able to find the document, but it’s also useful to be able to update it. We can use itMongoOfupdateMethod, which takes the first and second parameters of the document to be changed. Let’s update Vegetable Pizza to mushroom pizza:

$ db.pizza.update({ type: "Veggie" }, { type: "Mushroom" })

Now, if we rundb.pizza.find(), we should see that your document has been updated:

{ "_id" : ObjectId("5c7528b223ab40938c7dc536"), "type" : "Cheese" }
{ "_id" : ObjectId("5c7529fa23ab40938c7dc53e"), "type" : "Mushroom" }
{ "_id" : ObjectId("5c7529fa23ab40938c7dc53f"), "type" : "Olive" }

As with updating documents, we can also useMongoOfremoveMethod to delete a document. Let’s delete the mushroom pizza from the database:

$ db.pizza.remove({ type: "Mushroom" })

Now, if we execute the database:db.pizza.find() query, we only see two entries in the collection.

If we decide that we no longer want to include any data, we can run without empty object parametersremoveMethod, which clears the entire collection:

$ db.pizza.remove({})

Now, we have used it successfullyMongoDB ShellCreate a database, add documents to the collection, update them, and delete them. When we integrate the database into the project, these basic database operations will provide a solid foundation. In development, we can also useMongoDB ShellAccess the database. This is helpful for tasks such as debugging, manually deleting or updating entries.

Connect mongodb to our application

Now, you’ve moved fromshellI learned something about usingMongoDBLet’s connect it to our knowledgeAPIApplication. For this, we will useMongooseObject document mapper(ODM)。MongooseIs a library that reduces and simplifies style code through the use of pattern based modeling solutions, thus simplifying theNode.jsUsed in applicationsMongoDBThe amount of work required. Yes, you’re right – another model! As you can see, once the database schema is defined, theMongooseuseMongoDBThe way we areMongo ShellThe types of commands written in are similar.

We first need to update our local databaseURLYesenvDocuments. This will enable us to set up the database in any environment we are using, such as local development and productionURL

localMongoDBServer defaultURLbymongodb://localhost:27017, where we will add the database name. Therefore, in our countryenvFile, we will useMongoDatabase instanceURLSet up aDB_ The host variable is as follows:

DB_HOST=mongodb://localhost:27017/notedly

The next step in using the database in our application is to connect to it. Let’s write some code to connect our application to our database at startup. To that end, we will start withsrcCreate a directory nameddb.jsNew file for. staydb.jsIn, we will write the database connection code. We will also include a function to close the database connection, which will be useful for testing the application.

staysrc/db.jsEnter the following:

// Require the mongoose library
const mongoose = require('mongoose');

module.exports = {
  connect: DB_HOST => {
    // Use the Mongo driver's updated URL string parser
    mongoose.set('useNewUrlParser', true);
    // Use findOneAndUpdate() in place of findAndModify()
    mongoose.set('useFindAndModify', false);
    // Use createIndex() in place of ensureIndex()
    mongoose.set('useCreateIndex', true);
    // Use the new server discovery and monitoring engine
    mongoose.set('useUnifiedTopology', true);
    // Connect to the DB
    mongoose.connect(DB_HOST);
    // Log an error if we fail to connect
    mongoose.connection.on('error', err => {
      console.error(err);
      console.log(
        'MongoDB connection error. Please make sure MongoDB is running.'
      );
      process.exit();
    });
  },

  close: () => {
    mongoose.connection.close();
  }
};

Now, we will updatesrc/index.jsTo call this connection. To do this, we will first importenvConfiguration anddb.jsDocuments. In import, at the top of the file, add the following import:

require('dotenv').config();
const db = require('./db');

I like to be hereenvDefined in fileDB_ The host value is used as a variable. Add this variable directly to the port variable definition below:

const DB_HOST = process.env.DB_HOST;

Then, by adding the following to thesrc/index.jsFile, you can call our connection:

db.connect(DB_HOST);

src/index.jsThe document is now as follows:

const express = require('express');
const { ApolloServer, gql } = require('apollo-server-express');
require('dotenv').config();

const db = require('./db');

// Run the server on a port specified in our .env file or port 4000
const port = process.env.PORT || 4000;
// Store the DB_HOST value as a variable
const DB_HOST = process.env.DB_HOST;

let notes = [
  {
    id: '1',
    content: 'This is a note',
    author: 'Adam Scott'
  },
  {
    id: '2',
    content: 'This is another note',
    author: 'Harlow Everly'
  },
  {
    id: '3',
    content: 'Oh hey look, another note!',
    author: 'Riley Harrison'
  }
];

// Construct a schema, using GraphQL's schema language
const typeDefs = gql`
  type Note {
    id: ID
    content: String
    author: String
  }

  type Query {
    hello: String
    notes: [Note]
    note(id: ID): Note
  }

  type Mutation {
    newNote(content: String!): Note
  }
`;

// Provide resolver functions for our schema fields
const resolvers = {
  Query: {
    hello: () => 'Hello world!',
    notes: () => notes,
    note: (parent, args) => {
      return notes.find(note => note.id === args.id);
    }
  },
  Mutation: {
    newNote: (parent, args) => {
      let noteValue = {
        id: notes.length + 1,
        content: args.content,
        author: 'Adam Scott'
      };
      notes.push(noteValue);
      return noteValue;
    }
  }
};

const app = express();

// Connect to the database
db.connect(DB_HOST);

// Apollo Server setup
const server = new ApolloServer({ typeDefs, resolvers });

// Apply the Apollo GraphQL middleware and set the path to /api
server.applyMiddleware({ app, path: '/api' });

app.listen({ port }, () =>
  console.log(
    `GraphQL Server running at http://localhost:${port}${server.graphqlPath}`
  )
);

Although the actual function has not changed, if you runnpm run dev, the application should successfully connect to the database and run without errors.

Read and write data from our application

Now that we can connect to the database, let’s write the code we need to read data from and write data to the application.MongooseAllows us to define how data is treated asJavaScriptObjects are stored in the database, and then we can store and manipulate the data that matches the structure of the model. With that in mind, let’s create our object calledMongoosepattern.

First of all, in oursrcCreate a directory namedmodelsTo store the schema file. In this folder, create anote.jsI’m not sure. staysrc/models/note.jsIn, we will start with the basic settings of the definition file:

// Require the mongoose library
const mongoose = require('mongoose');

// Define the note's database schema
const noteSchema = new mongoose.Schema();

// Define the 'Note' model with the schema
const Note = mongoose.model('Note', noteSchema);
// Export the module
module.exports = Note;

Next, we’re going tonoteSchemaWe define our pattern in variables. Similar to the in memory data example, at present, our current structure will include the content of the note and the string representing the author. We will also include the option to add a timestamp to the note, which will be automatically stored when the note is created or edited. We will continue to add these features to the note structure.

oursMongooseThe structure of the model is as follows:

// Define the note's database schema
const noteSchema = new mongoose.Schema(
  {
    content: {
      type: String,
      required: true
    },
    author: {
      type: String,
      required: true
    }
  },
  {
    // Assigns createdAt and updatedAt fields with a Date type
    timestamps: true
  }
);

Data permanence

We will update and change the data model throughout the development process, sometimes removing all data from the database. Therefore, I do not recommend using this methodAPIStore important content, such as class notes, friends’ birthday lists, or navigation information to your favorite pizzas.

Now, our wholesrc/models/note.jsThe documentation should be as follows:

// Require the mongoose library
const mongoose = require('mongoose');

// Define the note's database schema
const noteSchema = new mongoose.Schema(
  {
    content: {
      type: String,
      required: true
    },
    author: {
      type: String,
      required: true
    }
  },
  {
    // Assigns createdAt and updatedAt fields with a Date type
    timestamps: true
  }
);

// Define the 'Note' model with the schema
const Note = mongoose.model('Note', noteSchema);
// Export the module
module.exports = Note;

To simplify importing models intoApollo Server ExpressApplication process, we will provideindex.jsAdd file tosrc/modelsIn the directory. This will merge our models into oneJavaScriptModule. Although it’s not strictly necessary, I think it’s a good strategy as the application and database models grow. staysrc/models/index.jsIn, we will import the note model and add it to the module object to export

const Note = require('./note');

const models = {
  Note
};

module.exports = models;

Now, by importing the module into thesrc/index.jsFile, we can merge the database module into theApollo Server ExpressIn the application code:

const models = require('./models');

After importing the database module code, we can make the parser save and read the database, not through the variables stored in memory. To do this, we will rewrite thenotesQuery, used by using theMongoDBTo extract notes from the database:

notes: async () => {
  return await models.Note.find();
},

After the server is running, we can access it in the browserGraphQL PlaygroundAnd run notes query:

query {
  notes {
    content
    id
    author
  }
}

The expected result will be an empty array because we haven’t added any data to the database (Fig5-1):

{
  "data": {
    "notes": []
  }
}

JavaScript everywhere Chapter 5 database (^_ ^)

chart5-1. Note query.

Update ournewNoteModify to add a note to our database, we will useMongoDBModularcreateMethod to accept an object.

Now, we will continue to write the author’s name:

newNote: async (parent, args) => {
  return await models.Note.create({
   content: args.content,
   author: 'Adam Scott'
  });
}

Now, we can visitGraphQL PlaygroundAnd write a modification that will add a note to our database:

mutation {
  newNote (content: "This is a note in our database!") {
  content
  author
  id
  }
}

Our modification will return a new note containing what we put into the variable, the name of the author, andMongoDBGeneratedID(Fig5-2)。

JavaScript everywhere Chapter 5 database (^_ ^)

chart5-2. Changes create new notes in the database

If you rerun the note query now, you should see the notes retrieved from the database! (see Fig5-3

JavaScript everywhere Chapter 5 database (^_ ^)

chart5-3. Our notes query returns the data in the database.

The last step is to useMongoDBThe unique number assigned to each entryIDrewritenoteTo extract specific notes from the database. For this, we will useMongooseOffindbyIdmethod:

note: async (parent, args) => {
  return await models.Note.findById(args.id);
}

Now we can use it in notes query ornewNoteThe only changes seen in the modificationIDQuery, you can retrieve a single note from the database. To do this, we will write a tapeidNote query based on parameters (Fig5-4):

query {
  note(id: "5c7bff794d66461e1e970ed3") {
   id
   content
   author
  }
}

Your note number

Used in the previous exampleIDIt is unique to my local database. Make sure to copy one from your own query or modification resultsID

JavaScript everywhere Chapter 5 database (^_ ^)

chart5-4. Query single note

Our ultimate goalsrc/index.jsThe document will be as follows:

const express = require('express');
const { ApolloServer, gql } = require('apollo-server-express');
require('dotenv').config();

const db = require('./db');
const models = require('./models');

// Run our server on a port specified in our .env file or port 4000
const port = process.env.PORT || 4000;
const DB_HOST = process.env.DB_HOST;

// Construct a schema, using GraphQL's schema language
const typeDefs = gql`
  type Note {
   id: ID
   content: String
   author: String
  }

  type Query {
   hello: String
   notes: [Note]
   note(id: ID): Note
  }

  type Mutation {
   newNote(content: String!): Note
  }
`;

// Provide resolver functions for our schema fields
const resolvers = {
  Query: {
   hello: () => 'Hello world!',
   notes: async () => {
    return await models.Note.find();
   },
   note: async (parent, args) => {
    return await models.Note.findById(args.id);
   }
  },
  Mutation: {
   newNote: async (parent, args) => {
    return await models.Note.create({
     content: args.content,
     author: 'Adam Scott'
    });
   }
  }
};

const app = express();

db.connect(DB_HOST);

// Apollo Server setup
const server = new ApolloServer({ typeDefs, resolvers });

// Apply the Apollo GraphQL middleware and set the path to /api
server.applyMiddleware({ app, path: '/api' });

app.listen({ port }, () =>
  console.log(
   `GraphQL Server running at http://localhost:${port}${server.graphqlPath}`
  )
);

Now, we can useGraphQL APIRead and write data from database! Try to add more notes, browse notes for all the notes. And browse the information content of single note query.

conclusion

In this chapter, you learned how to pass ourAPIuseMongoDBandMongooseLibrary. Database (e.gMongoDB)Enables us to store and retrieve application data securely. Object modeling libraries (for exampleMongoose)Simplify the work of database by providing tools for database query and data validation. We will update it in the next chapterAPIIn order to make the content of the database completeCRUD(create, read, update and delete) functions.

If there is any misunderstanding, please correct it. If you think it’s OK, please like it or share it. I hope it can help more people. :slightly_ smiling_ fac

Recommended Today

Implementation example of go operation etcd

etcdIt is an open-source, distributed key value pair data storage system, which provides shared configuration, service registration and discovery. This paper mainly introduces the installation and use of etcd. Etcdetcd introduction etcdIt is an open source and highly available distributed key value storage system developed with go language, which can be used to configure sharing […]