sailsjs use mongodb without ORM

后端 未结 2 1639
旧时难觅i
旧时难觅i 2021-01-28 12:47

I want to use mongodb with sails but without any ORM. So below is my service to connect mongodb.
Service:

//DbService.js

    const MongoClient = require(\'m         


        
相关标签:
2条回答
  • 2021-01-28 13:22

    As you can see in docs MongoClient.connect() doesn't return Promise object. Instead of this use callback function

    module.exports = {
      db:function(){
        var connect = MongoClient.connect("mongodb:***********", function (err, database) {
          //...
          }  
        });  
      }
    }
    

    btw. Your call DbService.db function in controller will also fail, cuz your service function also doesn't return Promise

    Before you go on, read something about Promises and callback functions

    0 讨论(0)
  • 2021-01-28 13:27

    First npm i mongodb because you'll need to wrap any ID's with new ObjectID(idStr).

    Then you can do this:

    const collection = Pet.getDatastore().manager.collection(Pet.tableName);
    const res = await collection.find({ name: { $regex: /blue/ } });
    const dataWithObjectIds = await res.toArray();
    const dataWithIds = JSON.parse(JSON.stringify(rawDataArr).replace(/"_id"/g, '"id"'));
    

    I created a helper function to do all of this for us:

    /**
     * Use by chaining as if you were acting on a collection. So can use .find .aggregate etc.
     * Returns json searializable data.
     *
     * @param {class} model A model
     * @param {number} cnt - Number of chains on this, so I know when it reached the end
     */
    function nativeMongoQuery(model, cnt) {
    
      const collection = model.getDatastore().manager.collection(model.tableName);
    
      let callCnt = 0;
    
      let req;
    
      const proxy = new Proxy({}, {
        get: (_, method) => (...args) => {
    
          if (!req) req = collection[method](...args);
          else req = req[method](...args);
    
          callCnt++;
    
          if (callCnt === cnt) {
            return (async function() {
              const rawDataArr = await req.toArray();
              return JSON.parse(JSON.stringify(rawDataArr).replace(/"_id"/g, '"id"'));
            })();
          } else {
            return proxy;
          }
        }
      });
    
      return proxy;
    
    }
    
    module.exports = nativeMongoQuery;
    

    I don't like the JSON parse and stringify and global replace. But if I don't do the stringify, then mongo _id's are all ObjectIds.

    Use it like this:

    const { ObjectId } = require('mongodb');
    
    function makeObjectId(id) {
       return new ObjectId(id);
    }
    
    const ownerIds = ['5349b4ffffd2781d08c09890f4', '5349b4ffffd2781d08c09890f5']
    const ownerObjectIds = ownerIds.map(makeObjectId);
    await nativeMongoQuery(Pet, 2).find({ owner: { $in: ownerObjectIds } }).sort({ dueAt: 1 });
    

    Here is another example:

    const mostRecentlyCreatedPets = await nativeMongoQuery(Pet, 1).aggregate([
      { $match: { owner: { $in: ownerObjectIds } } },
      { $sort: { createdAt: -1 } },
      { $limit: 1 }
    ]);
    

    The cnt argument tells you how many things you have chained off of there.

    0 讨论(0)
提交回复
热议问题