Completly new to mongoDB I'm trying to get the score field from a user in the "users" database that I have.
public static DBCursor getScore(String username) {
DBObject get = new QueryBuilder().put("name").is(username).get();
return getUsers().find(get);
}
Once I get the user object, how can I get the attribute that I want?
I suggest to use Jongo. It makes your life much more easier. Here is the website: http://jongo.org/
Related
import {favRestaurants} from '/lib/collections';
import {Meteor} from 'meteor/meteor';
import {check} from 'meteor/check';
export default function () {
Meteor.methods({
'favRestaurants.create' (id, name, rating, priceLevel, type) {
check(id, String);
check(name, String);
check(rating, Number);
check(priceLevel, Number);
check(type, String);
const createdAt = new Date();
const restaurant = {id, name, rating, priceLevel, type, createdAt};
if(check(Meteor.user()) == null){
console.log('onlye logged in users can data');
}else{
FavRestaurants.insert(restaurant);
}
}
});
}
This is my insert method for adding data to the restaurants collections. When i console log the 'check(Meteor.user())' in the console i get null as output. By that logic you shouldn't be able to add data to the collection, although this is still possible.
I would also like to make the FavResaurants collection personal for each user. Iv'e tried to check if there is a user and then adding a collection in the main.js file on the client side.
Meteor.loggingIn(() => {
console.log('check for user method');
var restId = 0;
if(Meteor.user() != null){
console.log('created new collection for the user');
const FavRestaurants = new Mongo.Collection('favRestaurants' + restId);
}
restId++;
});
I dont get any output to console using this method, which i found in the meteor docs. Is the code in the wrong place? Any help is much appriciated.
According to the docs the Accounts.ui.config is the method i should use. But I'm not sure in code i should put it. So far the placement of this method has resulted in my application crashing.
Answering your first question, to allow only logged-in clients to access a method, you should use something like:
if (!Meteor.userId()) {
throw new Meteor.Error('403', 'Forbidden');
}
Now, I see you want a collection to store favorite restaurants for each user in client side. But as I see it, there'd be only one logged in user per client, so you don't need a separate collection for each user (as the collection is in each client), you can just refer the user with it's id, and then fetch a user's favorite restaurants by a query like:
FavRestaurants.find({user: Meteor.userId()});
Moreover, as the docs suggest, Meteor.loggingIn is a method which tells you if some user is in the process of logging in. What you are doing is over-riding it, which doesn't make sense.
You should do something like:
if (Meteor.loggingIn()) {
// Do your stuff
}
Hope it gives you more clarity.
Creating a collection per user is a bad approach.
Define your favRestaurants collection once and add a owner field in the restaurant document before insert.
Create a publish method to publish to client side the userid favrestaurant only.
One more thing, check your userid first in your Meteor method, it will avoid unnecessary proces.
Regs
I can't seem to understand where I am going wrong currently when I attempt to update my User domain model that has a hasOne association to a Profile object.
My domain models are as follows:
class User {
static hasOne = [profile: Profile]
static fetchMode = [profile: 'eager']
ObjectId id
String username
}
class Profile {
static belongsTo = [user: User]
ObjectId id
String familyName
String givenName
}
I am able to persist a User with a profile originally but when attempting to update the User object I get validation errors.
Validation error occurred during call to save():
- Field error in object 'co.suitable.User' on field 'profile.familyName': rejected value [null]
- Field error in object 'co.suitable.User' on field 'profile.givenName': rejected value [null]
I am able to print out the user.profile ID and also the user.profile.familyName before saving the object. Like the following:
println(user.profile.familyName)
println(user.profile.id.toString())
user.save(flush: true, failOnError: true)
But I still get the validation errors before saving, i'd imagine that the println(user.profile.familyName) call is fetching the profile object if it already hasn't been loaded which I thought setting the fetchMode would have handled.
The object is able to successfully persist and save when I do:
user.profile = Profile.findById(user.profile.id)
println(user.profile.id.toString())
user.save(flush: true, failOnError: true)
I could wrap that in a service but I was hoping for a solution that would be handled by Grails if possible. Any advice or thoughts is much appreciated.
You should not apply the logic for the SQL DB to Mongo 1 to 1. Mongo and other document-oriented DBs are not originally intended to store the joins between collections. There are some workarounds, like db-refs, but they are to be used with caution.
For your case - with hasOne - I would suggest using mongo's subdocuments (mirrored as GORM's embedded objects) instead of referencing:
class User {
ObjectId id
String username
Profile profile
static embedded = [ 'profile' ]
}
class Profile {
String familyName
String givenName
}
thus you use the mongo in accordance to it's original puprose. Also querying is simpler and faster.
I need to query a collection based on a list of parameters.
For example my model is:
public class Product
{
string id{get;set;}
string title{get;set;}
List<string> tags{get;set;}
DateTime createDate{get;set;}
DbReference<User> owner{get;set;}
}
public class User
{
string id{get;set;}
...other properties...
}
I need to query for all products owned by specified users and sorted by creationDate.
For example:
GetProducts(List<string> ownerIDs)
{
//query
}
I need to do it in one query if possible not inside foreach. I can change my model if needed
It sounds like you are looking for the $in identifier. You could query products like so:
db.product.find({owner.$id: {$in: [ownerId1, ownerId2, ownerId3] }}).sort({createDate:1});
Just replace that javascript array [ownerId1, ...] with your own array of owners.
As a note: I would guess this query is not very efficient. I haven't had much luck with DBRefs in MongoDB, which essentially adds relations to a non-relational database. I would suggest simply storing the ownerID directly in the product object and querying based on that.
The solution using LINQ is making an array of user IDs and then do .Contains on them like that:
List<string> users = new List<string>();
foreach (User item in ProductUsers)
users .Add(item.id);
return MongoSession.Select<Product>(p => users .Contains(p.owner.id))
.OrderByDescending(p => p.createDate)
.ToList();
I need to iterate through all of the collections in my MongoDB database and get the time when each of the collections was created (I understand that I could get the timestamp of each object in the collection, but I would rather not go that route if a simpler/faster method exists).
This should give you an idea of what I'm trying to do:
MongoDatabase _database;
// code elided
var result = _database.GetAllCollectionNames().Select(collectionName =>
{
_database.GetCollection( collectionName ) //.{GetCreatedDate())
});
As far as I know, MongoDB doesn't keep track of collection creation dates. However, it's really easy to do this yourself. Add a simple method, something like this, and use it whenever you create a new collection:
public static void CreateCollectionWithMetadata(string collectionName)
{
var result = _db.CreateCollection(collectionName);
if (result.Ok)
{
var collectionMetadata = _db.GetCollection("collectionMetadata");
collectionMetadata.Insert(new { Id = collectionName, Created = DateTime.Now });
}
}
Then whenever you need the information just query the collectionMetadata collection. Or, if you want to use an extension method like in your example, do something like this:
public static DateTime GetCreatedDate(this MongoCollection collection)
{
var collectionMetadata = _db.GetCollection("collectionMetadata");
var metadata = collectionMetadata.FindOneById(collection.Name);
var created = metadata["Created"].AsDateTime;
return created;
}
The "creation date" is not part of the collection's metadata. A collection does not "know" when it was created. Some indexes have an ObjectId() which implies a timestamp, but this is not consistent and not reliable.
Therefore, I don't believe this can be done.
Like Mr. Gates VP say, there is no way using the metadata... but you can get the oldest document in the collection and get it from the _id.
Moreover, you can insert an "empty" document in the collection for that purpose without recurring to maintain another collection.
And it's very easy get the oldest document:
old = db.collection.find({}, {_id}).sort({_id: 1}).limit(1)
dat = old._id.getTimestamp()
By default, all collection has an index over _id field, making the find efficient.
(I using MongoDb 3.6)
Seems like it's some necroposting but anyway: I tried to find an answer and got it:
Checked it in Mongo shell, don't know how to use in C#:
// db.payload_metadata.find().limit(1)
ObjectId("60379be2bec7a3c17e6b662b").getTimestamp()
ISODate("2021-02-25T12:45:22Z")
I want to retrieve the last inserted _id, using mongoose as MongoDB wrapper for node.js. I've found the following tutorial, but I can't change any node modules because the app runs on a public server:
Getting "Last Inserted ID" (hint - you have to hack Mongoose)
Any other ideas? This what I want to do:
Insert new user
Get user's _id value
Set a new session based on user's id
Redirect to /
Thanks!
I'm using mongoose version 1.2.0 and as soon as I created a new instance of a mongoose model, the _id is already set.
coffee> u = new User()
[object Object]
coffee> u._id
4dd68fc449aaedd177000001
I also verified that after I call u.save() the _id remains the same. I verified via MongoHub that this is indeed the real ID saved into MongoDB.
If you explicitly declare
_id: Schema.ObjectId
for your model, then the ObjectId will not be available after new or save.
This is probably a bug.
If you're looking to get the last inserted _id of a sub object, then create the object, and add it to the item. Here's an example in NowJS using MongoDB and Mongoose (to add some schema sugar) which then converts the result to JSON to send back to the client:
var nowRoomID = this.now.room;
var Conversation = mongoose.model('Conversation');
Conversation.findById(convID, function(error, conversation) {
var Blip = mongoose.model('Blip');
var createdBlip = new Blip();
createdBlip.author= nowUserName;
createdBlip.authorid = parsed.authorid;
createdBlip.body = revisedText;
createdBlip.created_at = new Date();
createdBlip.modified_at = new Date();
conversation.blips.push(createdBlip);
parsed._id = createdBlip._id; //NOTE: ID ACCESSED HERE
message = JSON.stringify(parsed);
conversation.save(function (err) {
if (!err) {
console.log('Success - saved a blip onto a conversation!');
nowjs.getGroup(nowRoomID).now.receiveMessage(nowUserName, message);
}
});
With MongoDB, if you don't explicitly set a document's _id value then the client driver will automatically set it to an ObjectId value. This is different from databases that might generate IDs on the server and need another query to retrieve it, like with SQL Server's scope_identity() or MySQL's last_insert_id().
This allows you to insert data asynchronously because don't need to wait for the server to return an _id value before you continue.
So, as shown is Peter's answer, the _id is available before the document is saved to the database.
I just get the id from the document passed to the callback, since save returns the saved document.
Check below url
http://mongodb.github.io/node-mongodb-native/markdown-docs/insert.html
you will find following code in given url
var document = {name:"David", title:"About MongoDB"};
collection.insert(document, {w: 1}, function(err, records){
console.log("Record added as "+records[0]._id);
});