How do I use a variable as a field name in a Mongo query in Meteor? - javascript

How would I go about using a variable as a field name in a Mongo query in a Meteor application.
Here is an example...
This runs a find on my request controllers collection after capitalizing the collection name for the parent id of a child. The child is the users field.
window[Meteor.request.controller.capitalise()]["find"]({ _id: Session.get('parent_id'), users: params.child }).count()
As you can see my controller is a variable name for the collection item which allows me to have a single line of code for finding children of controller/collections but I need to be able to set the child field name to a variable. In the above example that would be users but I want it to be a variable name.
I have tried this but it does not work.
window[Meteor.request.controller.capitalise()]["find"]({ _id: Session.get('parent_id'), [Session.get('child_collection_name').decapitalise()]: params.child }).count()
where
Session.get('child_collection_name').decapitalise()
returns users
Any ideas? If I can figure out how to use a variable name in a mongo query in meteor it would reduce my code footprint significantly.

The query is just a JavaScript object, so you can build it step by step:
var query = { _id: Session.get('parent_id') };
var myCustomField = Session.get('child_collection_name').decapitalise();
var myCustomValue = params.child;
query[myCustomField] = myCustomValue;
var count = SomeCollection.find(query).count();
Does that do the trick?

Related

Updating Query in Firestore

I am new to Firestore, need some help on firestore update.
I have following structure and wants to update "employee name" property. Not sure how to select and update.
Department:[
Name: Accounts
Employee:[
{Name :David,
Age :25},
{Name:Paul,
Age:27}
]
]
Here is what I was trying to do:
let depempCollectionRef = admin.firestore().collection('DepEmployee').doc('depempid')
depempCollectionRef.Department.Employee
.update({ name: 'Scott' },{merge:true})
.then(function() { console.log("Document successfully updated!"); })
Employee is just an embedded data structure in your Firestore document ā€“ so you can't address it through the reference directly. As far as Firestore is concerned, Employee is just an attribute on the Department document as Name is.
Before I propose a solution, let me point out two things:
If using update, you don't need {merge: true}. You use {merge: true} together with set to get an update-like behavior, if the document already exists.
I wouldn't use an Array of employees. It might make more sense to store the employees in their own collection in Firestore and then just list their reference IDs (= foreign keys) here. As a general rule of thumb: try to keep your data structure flat. Also use Arrays only, if you need to maintain a certain order of items.
A) If you have a separate collection for employees, updating the name is as easy as:
employeeCollection.doc('101').update({name: 'Scott'})
B) If you want to store employee data within your department document, I would still store them as a map with IDs (instead of an Array) and then access them with dot notation:
Department:[
Name: Accounts
Employees:{
101: {
Name :David,
Age :25
},
102: {
Name:Paul,
Age:27
}
}
]
depempCollectionRef.Department
.set({ ['101.name']: 'Scott' }, {merge:true})
C) And if you really want to store the data embedded in an Array, I believe you have to read and update the whole Array (not sure, if there is a better solution):
const employeesSnap = await depempCollectionRef.Department.get()
const updatedEmployees = changeNameOfScottInArray()
depempCollectionRef.Department
.update({ 'Employees': updatedEmployees })
I didn't test this code, but I hope you get the gist of it!
I'd recommend you flatten your data structure by creating a separate Employee collection and then just referencing them by their foreign key in your department (solution A).

How to access firebase db sub object elements?

My firebase db structure is given below,
users
fb-user-key1
user1-details1
Tags
Tag-key1
"name":"value"
Tag-key2
"name":"value"
fb-user-key2
user1-details2
Tags
Tag-key1
"name":"value"
Tag-Key1 & user-key's are generated by firebase with push(). firebase code to access the content is,
var fbref = firebase.database().ref("users");
fbref.child("Tags").on("child_added", function(e){
var Tagobj = e.val().name;
console.log(Tagobj);
});
This one is not returning anything. I am not able to access name:value pair in the above data structure.
`
adding modified code,
firebase.database().ref("users").on("child_added",function(eā€Œā€‹) { var Tagobj = e.val().Tags; });
Output of the above code is output data structure
How to access that name value pairs?? firebase keys are issue?
Not getting, where I am wrong. Appreciate your inputs.
Since Tags is a child property of each user, then you have to read it off of each user object.
If you want all Tags for all users, assuming Tags for each user is not updated after a user is created, you can do this:
tagsPerUserId = {};
firebase.datatabs().ref('users').on('child_added', function(snap) {
tagsPerUserId[snap.key] = snap.value().Tags;
// TODO: Notify view that tagerPerUserId is updated and needs to be re-rendered
console.log(`Tags for userId ${snap.key}: ${snap.value().Tags}`);
});
This way you will also get Tags of new users when they are created, but you will not get updates to Tags of existing users.

Select all the fields in a mongoose schema

I want to obtain all the fields of a schema in mongoose. Now I am using the following code:
let Client = LisaClient.model('Client', ClientSchema)
let query = Client.findOne({ 'userclient': userclient })
query.select('clientname clientdocument client_id password userclient')
let result = yield query.exec()
But I want all the fields no matter if they are empty. As always, in advance thank you
I'm not sure if you want all fields in a SQL-like way, or if you want them all in a proper MongoDB way.
If you want them in the proper MongoDB way, then just remove the query.select line. That line is saying to only return the fields listed in it.
If you meant in a SQL-like way, MongoDB doesn't work like that. Each document only has the fields you put in when it was inserted. If when you inserted the document, you only gave it certain fields, that document will only have those fields, even if other documents in other collections have different fields.
To determine all available fields in the collection, you'd have to find all the documents, loop through them all and build an object with all the different keys you find.
If you need each document returned to always have the fields that you specify in your select, you'll just have to transform your object once it's returned.
const fields = ['clientname', 'clientdocument', 'client_id', 'password', 'userclient'];
let Client = LisaClient.model('Client', ClientSchema)
let query = Client.findOne({ 'userclient': userclient })
query.select(fields.join(' '))
let result = yield query.exec()
fields.forEach(field => result[field] = result[field]);
That forEach loop will set all the fields you want to either the value in the result (if it was there) or to undefined if it wasn't.
MongoDB is schemaless and does not have tables, each collection can have different types of items.Usually the objects are somehow related or have a common base type.
Retrive invidual records using
db.collectionName.findOne() or db.collectionName.find().pretty()
To get all key names you need to MapReduce
mapReduceKeys = db.runCommand({
"mapreduce": "collection_name",
"map": function() {
for (var key in this) {
emit(key, null);
}
},
"reduce": function(key, stuff) {
return null;
},
"out": "collection_name" + "_keys"
})
Then run distinct on the resulting collection so as to find all the keys
db[mapReduceKeys.result].distinct("_id") //["foo", "bar", "baz", "_id", ...]

Update Array from Document (MongoDB) in Javascript not Working

I've looking for an answer for like 5 five hours straight, hope somebody can help. I have a MongoDb collection results (I'm using mLab) which looks like this:
{
"user":"5818be9c74aaec1824c28626"
"results":[{
"game_id":14578,
"level1":-1,
"level2":-1,
"level3":-1
},
{ ....
}],
{ "user":....
}
}
"user" is a MongoID I save in a previous part of the code, "results" is a record of scores. When an user does a new score, I have to update the score of the corresponding level (I'm using NodeJS).
This is one of the things I've tried so far.
app.get('/levelCompleted/:id/:time', function (request, response) {
var id = request.params.id;
var time = parseInt(request.params.time);
var u= game.getUserById(id);
var k = "results.$.level"+(u.level);
//I build the key to update dinamycally
dbM.collection("results").update(
{user:id,
"results.game_id":u.game_id
//u has its own game_id
},
{$set: {k:time}}
);
...
response.send(...);
});
I've checked the content of every variable and parameter, tried also using $elemMatch and dot notation, set upsert and multi, with no results. I've used an identical command on mongo shell and it has work on the first try.
Update with Mongo Shell
If someone could tell me what I'm doing wrong or point me in the right direction, it would be great.
Thanks
When you use a MongoId as a field in a MongoDB, you can't just pass a string with the id to do the query, you have to identify that string as an ObjectId (Id type in Mongo). Just add a new require in your node.js file.
var ObjectID = require("mongodb").ObjectID;
And use the imported constructor in your update request.
dbM.collection("results").update(
{user:ObjectID(id),...
...
}

MarkLogic: find by property value

I have a MarkLogic 8 database:
declareUpdate();
var book0 = {
id: fn.generateId({qwe: 'book'}),
username: 'book',
password: 'pass'
};
var book1 = {
id: fn.generateId({asd: 'book'}),
username: 'user',
password: 'pass1'
};
xdmp.documentInsert(
'zz' + book0.id,
book0,
xdmp.defaultPermissions(),
['qwe']);
xdmp.documentInsert(
'xx' + book1.id,
book1,
xdmp.defaultPermissions(),
['qwe']);
So I want to find them by name with the Node.js API:
var db = marklogic.createDatabaseClient(connection.connInfo);
var qb = marklogic.queryBuilder;
function findByName(name) {
return db.documents.query(
qb.where(
qb.collection('qwe'),
qb.value('username', name)
)
).result();
}
The problem is that it finds not only user or user0, but also users and if I create a document with username book it will find both book and books.
A values query matches the entire text of a JSON property by stemming each word in the text (if stemming is enabled, which is the default).
Where (as in this case) that's not what you want, you can do either of the following:
Create a string range index (with the root collation if you only need exact matches) for the JSON property
Turn on word searches in the database configuration and use the "unstemmed" option on the query.
If you also turn off stemmed search in the database configuration, you don't have to pass the option (and avoid the extra resource required for both types of indexes).
To limit the configuration change to a specific property, you can configure a field for the property instead of configuring the entire database.
For more background, see:
http://docs.marklogic.com/guide/search-dev/stemming
http://docs.marklogic.com/guide/admin/text_index
http://docs.marklogic.com/cts.jsonPropertyValueQuery?q=cts.jsonPropertyValueQuery&v=8.0&api=true
Hoping that helps,

Categories

Resources