I been working on LokiJS on Node recently, And I could'nt find a command that deletes the entire Collection itself,
I tried with these commands with an assumption it would exist, I could not find any docs/ samples to delete a collection.
// let result = this.db.dropCollection(collectionName);
// let result = this.db.removeCollection(collectionName);
// let result = this.db.deleteCollection(collectionName);
Other way around I know I can achieve the same by reading the file and removing the entire object, But is there a built-in LokiJS function?
To delete a collection you need to use the removeCollection() method on the main Loki object. See docs here.
For example, if you have your Loki instance initialized like this:
const loki = require('lokijs');
const lokidb = new loki();
// Add a collection (that we will remove later)
let myCollection = lokidb.addCollection('myCollection');
Now lokidb is your main loki object, and this is the object that you need to execute the removeCollection() from.
// Let's remove the collection
lokidb.removeCollection('myCollection');
// * poof * ....
// myCollection is now gone
// To make sure that this deleting change is persisted (if necessary)
lokidb.saveDatabase();
I don't know exactly how you have your loki db set up, but hopefully this example helps.
Related
I've been working on chrome extention project.
What I am trying to do is store the input value and pull it out when the specific button is pressed.
Below is the part of js code:
import { Dexie } from '../node_modules/dexie/dist/dexie.mjs';
var DBName = 'test';
buttonA.addEventListener('click', () => {
const inp = document.getElementById("inp");
const db = new Dexie(DBName);
db.version(2).stores({
friend: '++id, name'
});
db.friend.add({
name: inp.value
})
});
buttonB.addEventListener('click', () => {
const db = new Dexie(DBName);
const ch = db.friend;
console.log("Checking the value in DB: " + ch);
});
When I try it, it stores whatever input to indexed DB after clicking buttonA (confirmed by using Chrome Developer Tool), however when it comes to clicking on buttonB, the log tells that ch is undefined (same for db.friend.name or db.name as well).
Because of this, even when I use get(), it returns me an error since I am accessing on undefined variable.
Could someone help figuring out why the program does not access properly to an indexed DB that exists when I click on a buttonB?
Thank you.
Problems:
The second instance of Dexie does not declare which tables there are, so db.friend is unknown.
Your code creates a new Dexie for every click. It would be much better and faster to reuse a single Dexie instance. If you create a new Dexie instance everytime, you must also close it after you to avoid resource leakage.
Recommendation:
Declare a singleton Dexie instance with version().stores(...) so it populates the 'friend' property for you.
Preferably this code could be in it's own module (such as 'db.js').
Use that single Dexie instance from any place where you need to store or read from the db.
New to MongoDB, very new to Atlas. I'm trying to set up a trigger such that it reads all the data from a collection named Config. This is my attempt:
exports = function(changeEvent) {
const mongodb = context.services.get("Cluster0");
const db = mongodb.db("TestDB");
var collection = db.collection("Config");
config_docs = collection.find().toArray();
console.log(JSON.stringify(config_docs));
}
the function is part of an automatically created realm application called Triggers_RealmApp, which has Cluster0 as a named linked data source. When I go into Collections in Cluster0, TestDB.Config is one of the collections.
Some notes:
it's not throwing an error, but simply returning {}.
When I change context.services.get("Cluster0"); to something else, it throws an error
When I change "TestDB" to a db that doesnt exist, or "Config" to a collection which doesn't exist, I get the same output; {}
I've tried creating new Realm apps, manually creating services, creating new databases and new collections, etc. I keep bumping into the same issue.
The mongo docs reference promises and awaits, which I haven't seen in any examples (link). I tried experimenting with that a bit and got nowhere. From what I can tell, what I've already done is the typical way of doing it.
Images:
Collection:
Linked Data Source:
I ended up taking it up with MongoDB directly, .find() is asynchronous and I was handling it incorrectly. Here is the reply straight from the horses mouth:
As I understand it, you are not getting your expected results from the query you posted above. I know it can be confusing when you are just starting out with a new technology and can't get something to work!
The issue is that the collection.find() function is an asynchronous function. That means it sends out the request but does not wait for the reply before continuing. Instead, it returns a Promise, which is an object that describes the current status of the operation. Since a Promise really isn't an array, your statment collection.find().toArray() is returning an empty object. You write this empty object to the console.log and end your function, probably before the asynchronous call even returns with your data.
There are a couple of ways to deal with this. The first is to make your function an async function and use the await operator to tell your function to wait for the collection.find() function to return before continuing.
exports = async function(changeEvent) {
const mongodb = context.services.get("Cluster0");
const db = mongodb.db("TestDB");
var collection = db.collection("Config");
config_docs = await collection.find().toArray();
console.log(JSON.stringify(config_docs));
};
Notice the async keyword on the first line, and the await keyword on the second to last line.
The second method is to use the .then function to process the results when they return:
exports = function(changeEvent) {
const mongodb = context.services.get("Cluster0");
const db = mongodb.db("TestDB");
var collection = db.collection("Config");
collection.find().toArray().then(config_docs => {
console.log(JSON.stringify(config_docs));
});
};
The connection has to be a connection to the primary replica set and the user log in credentials are of a admin level user (needs to have a permission of cluster admin)
I am trying to get a document from a collection, but it doesn't seem to be working.
when i use the find().fetch(), it returns only an empty array. my code is as follows.
var users = new Mongo.Collection("users");
console.log(users.find());
var userRecord = users.find().fetch();
var returnUserRecord = {};
if (userRecord.length >0){
returnUserRecord = {username:userRecord.username, loginHash:userRecord.loginHash};
console.log("if statement is not complete and the value of the return variable is");
console.log(returnUserRecord);
}
return returnUserRecord
I have checked the database directly and noticed that there is indeed a document in the collection with the command:
meteor mongo
if it makes any difference, all this code in the in the server js file, and is being called from from the client by: Meteor.Methods()/Meteor.call()
EDIT 1
i created another collections with new data from the client, and after selecting the correct database, and running the command:
meteor:PRIMARY> db.newCollection1.find()
i get:
{ "_id" : ObjectId("55d1fa4686ee75349cd73ffb"), "test1" : "asdasd", "test2" : "dsadsa", "test3" : "qweqwe" }
so this confirms that it is available in the database, but running the following in the client console, still doesnt return the result. (autopublish is installed. i tried removing autopublish and made the appropriate changes to subscribe to the table, but that didnt work either).
var coll = new Meteor.Collection('newCollection1');
coll.find().fetch()
this returned an empty array. i have also tried the same on the server.js code using:
meteor debug
but i am still getting an empty array. does anyone know what i might be doing wrong here?
SOLUTION
the solution for this was to create the collection variable in the Meteor object context. this way it can be accessed from the Meteor context.
i.e.
Meteor.coll = new Meteor.Collection('newCollection1');
Meteor.coll.find().fetch();
i hope this helps someone. depending on your code you may want to use a different context.
You don't wait for this subscription to complete, therefore you get empty array.
You should probably read this or this to better understand it.
The thing is you connect users variable to "users" collection, and when you call it, it isn't yet polluted with data (if you don't want to use subscription then maybe use helper - it's reactive so it will return proper value when subscrtiption is finished)
Did you subscribe your users collection somewhere?
if (Meteor.isServer) {
Meteor.publish("users", function(){
return Users.find({})
});
}
if (Meteor.isClient) {
Meteor.subscribe("users");
}
First of all some advice: you can not define a collection twice. If you call new Mongo.Collection("users") a second time you will get an error. Therefore, it should be a global variable an not inside a method.
What I can see in your code is that you are trying to use an array as if it were an object. userRecord.username wont work because userRecord has the value of the fetch() which returns an array.
You could either change your code to userRecord[0].username or loop over the results with forEach like so:
var users = new Mongo.Collection("users");
console.log(users.find());
users.find().forEach(function(singleUser){
console.log(EJSON.stringyfy(singleUser));
}
in order to return the first user, you would be better of using findOne which returns the first object in the result.
This is a follow-up to a question I posted earlier today. I'm going through this book on using AngularJS with Firebase, which lead me to post this question. I found a solution, but what I still don't understand is that the example in the API Documentation for a $firebaseArray doesn't seem to be handling it as an asynchronous request.
var list = $firebaseArray(new Firebase(URL));
// add an item
list.$add({ foo: "bar" }).then(...);
// remove an item
list.$remove(2).then(...);
// make the list available in the DOM
$scope.list = list;
Also, the example from the books seems to treat the request synchronously as well.
# Service
var buildingsUri = FIREBASE_URI + '/buildings';
var ref = new Firebase(buildingsUri);
var buildings = $firebaseArray(ref);
var getBuildings = function () {
return buildings;
};
...
# Controller
$scope.buildings = syncArraySvc.getBuildings();
How is it that $scope.list in the first example and $scope.buildings in the second example could be properly populated with data when they haven't checked to make sure the request has completed?
The $add and $remove methods return promises. The $firebaseArray() method returns an array with some special functions and properties added. Neither $add or $remove require the data to be loaded locally or depend on the state of the data, so they can be called synchronously. The data is still downloaded asynchronously, of course. So, for example:
var list = $firebaseArray(new Firebase(URL));
// add an item
list.$add({ foo: "bar" }).then(function(ref) {
console.log('added', ref.key());
});
// remove an item
list.$remove(2).then(function(ref) {
console.log('removed', ref.key());
});
console.log('list current contains', list.length, 'items');
list.$loaded(function() {
console.log('after loading initial data, the list contains', list.length, 'items');
});
Assuming the list contains 10 items at load time, and that list is not changed remotely during this code execution, we would see output similar to the following:
list currently contains 0 items
after loading initial state, the list contains 10 items
added abc123
removed xyz456
Additionally, I'd note that this code is probably superfluous. Usually when we see code like this, it's because devs are trying to turn Firebase into a CRUD model. You can probably just return $firebaseArray() there instead and use the existing methods like $getRecord(), et al, instead of artificially wrapping the API in your service.
So I have module "bot.js" and in this module, it constantly checks for messages and assigns them to a variable (db_users). Since I run my app from "app.js", and I pass the functions that continuously populates db_users, how do I get this information to "app.js"?
Bot.js is using an IRC function that stores user's messages.
var db_users = []
// I then populate db_users with the previous data that is already in mongodb
// using a .find().exec() mongodb command.
bot.addListener('message', function (from, to, text) {
userInfo.checkForUser(db_users);
// checkForUser basically looks through the variable db_users to see if
// there is a username that matches the "from" parameter in the listener
// If it's not there, push some user information into the db_users array
// and create a new MongoDB record.
}
So I have all this, but my main app is a website that can control this "bot" (It's not a spam bot, but a moderation/statistical bot), and I'm using a require function to use "./bot.js" in "app.js"
app.js
bot = require('./bot');
So how would I constantly use the data in bot.js, in app.js? I'm a little fuzzy on how modules work.
Yeah I could just put all of the contents of app.js in bot.js, but it would be too annoying to look through.
Thanks!
Put db_users inside an object so that it's just a reference. Make changes to that reference instead. Then export that outer object. Now since db_users is just a reference, it'll always be a latest copy of whatever it refers to.
bot.js
var data = module.exports = {};
data.db_users = [];
bot.addListener('message', function (from, to, text) {
userInfo.checkForUser(data.db_users);
}
app.js
botData = require('./bot');
botData.db_users will always have the whatever latest changes were made to data.db_users in bot.js