I need to find a way to auto-increment the "Bill_id" field by 1 , whenever I insert a new item to a nested array in a collection:
this is the structure of the nested document
I also found this demo on the official documentation :
https://docs.mongodb.com/v3.0/tutorial/create-an-auto-incrementing-field/
function getNextSequence(name) {
var ret = db.counters.findAndModify(
{
query: { _id: name },
update: { $inc: { seq: 1 } },
new: true
}
);
return ret.seq;
}
but I didn't know how to use the solution because it's proposing a JavaScript function that does all the work
However I am working with python script , and to be specific a REST API using flask
Write a similar function mentioned in the docs, in python. This is what I use.
def getLastUserId(self):
if len(list(self.find())) is not 0:
last_user = list(self.find({}).sort("user_id", -1).limit(1))
return last_user[0]["user_id"]
else:
return 0
This will return the "user_id" of the last added document. Just increment it by one, and do a simple insert for the new document.
Related
I have uploaded the following JSON file into a mongoDB database:
https://cloudpricingcalculator.appspot.com/static/data/pricelist.json
I have succeeded in accessing it using the following line in my app.js:
db.googlepricelist.find({},
{"gcp_price_list":1}).pipe(JSONStream.stringify()).pipe(res);
I would like to query all objects in object gcp_price_list, where the name of the object contains substring "VMIMAGE".
So for example bellow objects:
"CP-COMPUTEENGINE-VMIMAGE-F1-MICRO"
"CP-COMPUTEENGINE-VMIMAGE-G1-SMALL"
I can't figure out how to define a query which is able to do this.
So far I tried this:
db.googlepricelist.find({$where: function() {
for (var key in this.gcp_price_list) {
if (key.indexOf("VMIMAGE")!=-1) {
return true;
}
return false;
}
},}).pipe(JSONStream.stringify()).pipe(res);
This should get you going and works from v3.4.4 onwards:
db.googlepricelist.aggregate({
$project: {
"gcp_price_list_as_array": { $objectToArray: "$gcp_price_list" }, // transform "gcp_price_list" into an array of key-value pairs
}
}, {
$unwind: "$gcp_price_list_as_array" // flatten array
}, {
$match: { "gcp_price_list_as_array.k": /VMIMVAGE/ } // like filter on the "k" (as in "key") field using regular expression
})
You'd normally attempt to use $filter to filter the array which, however, doesn't work using a regular expression. There's an open JIRA ticket for that but it's simply not yet available.
I have an array of "any" type with multiple objects inside of it, as so:
//List of posts (array)
this.posts = [
//First Post (object)
{
userFirst: 'Teyah',
userLast: 'Tharpe',
postText: 'Good morning, everyone! Have a good day. :)',
//First Post's comments (array)
comments: [
//First Comment (object)
{
cFirstName: 'Jalen',
cLastName: 'Tharpe',
theirComment: 'Thank you'
},
//Second Comment (object)
{
cFirstName: 'Gerald',
cLastName: 'Matthews',
theirComment: 'Thank you! You do the same.'
}
]
},
//Second Post (object)
{
userFirst: 'Jordan',
userLast: 'Gibson',
postText: 'What is the move for today?',
comments: [
{
cFirstName: 'Joshua',
cLastName: 'Stewart',
theirComment: 'Party at my house!!!'
}
]
}
];
As you can see, I have an array of posts, which contains objects, and within the post objects, I have a list of comments. I am trying to apply a comment()function, to only one of the objects. Say, posts[0]. Can someone let me know if this is within scope for Angular 2? If so, please help.
If more code/information is needed, please let me know.
Thank you.
Yes, this is within the scope of Angular, as it is in the scope of javascript! The detailed answer to your question depends on exactly what you want to do with your comment() function. I will try to anticipate a couple of things you might like to do.
Add a new comment to a certain post's comment array
addComment(post, comment) {
post.comments.push(comment);
}
Find a post based on its index and add a comment
addCommentUsingIndex(postIndex, comment) {
this.posts[postIndex].comments.push(comment);
}
Extract the number of comments for a given post
countComments(postIndex) {
return this.posts[postIndex].comments.length;
}
get an array of the full names of each commenter of a certain post
transformComments(postIndex) {
return this.posts[postIndex].comments.map(comment => {
return comment.cFirstName + ' ' + comment.cLastName
});
}
Does that roughly cover your requirements?
{"__v":0,"_id":{"$oid":"55f13d34258687e0bb9e4385"},"admin":true,"email":"emaple1#gmail.com","last_login":"11:25:24 AM","name_surname":"user1","password":"qwerty123"}
{"__v":0,"_id":{"$oid":"55ef49dd5d610eab18719deb"},"admin":true,"email":"emaple2#gmail.com","last_login":"12:25:24 AM","name_surname":"user2","password":"qwerty123"}
{"__v":0,"_id":{"$oid":"55f0173bb3322bf560724fd1"},"admin":true,"email":"emaple3#gmail.com","last_login":"10:25:24 AM","name_surname":"user3","password":"qwerty123"}
Hello, I working in nodeJS file and there I have a collection of JSON objects and I would like to make a search through it. For each user from this list I need to compare the field "last_login" .
I am new to nodeJS can someone help? Thank you!
This is what i have tried:
User.find({}, {last_login: }, function(err, docs) {
if (err) {
return res.json({ success: false, message: 'Failed to display last logins.' });
}
docs.forEach(function(doc, index) {
res.json({success: true, message: 'time of last login', last_login: doc.last_login});
})
//res.json(users);
});
});
Where last_login is a field in the User object and basically I need to iterate over all users in the db and extract only the last_login and display in in the response.I don’t know what value to put in the find() inside the curly braces
this is the part where I am stuck
I’ve slightly changed the function and it returns a JSON object containing the info about one user that is matched with the search query. The problem is, the console displays the result, as a whole object, although I want to get only a specific key value pair and namely last_login: value
function searchByUserName(name_surname) {
return list.filter(function(user) {
return user.name_surname === name_surname;
});
}
var a = searchByUserName('user1');
for (last_login in a ) {
if (a.hasOwnProperty(last_login)) {
console.log("last_login" + "=" + JSON.stringify(a[last_login]))
}
}
Can you tell me please, what change to make in order to get only the last_login key
here is a sample result from the console.log() that I receive:
last_login={"__v":0,"_id":{"$oid":"55f13d34258687e0bb9e4385"},"admin":true,"email":"emaple1#gmail.com","last_login":"11:25:24 AM","name_surname":"user1","password":"qwerty123"}
although I want last_login = “last_login”: 11:25:24 AM
Assuming it's an array of objects like bellow.
var users = [{"__v":0,"_id":{"$oid":"55f13d34258687e0bb9e4385"},"admin":true,"email":"emaple1#gmail.com","last_login":"11:25:24 AM","name_surname":"user1","password":"qwerty123"},
{"__v":0,"_id":{"$oid":"55ef49dd5d610eab18719deb"},"admin":true,"email":"emaple2#gmail.com","last_login":"12:25:24 AM","name_surname":"user2","password":"qwerty123"},
{"__v":0,"_id":{"$oid":"55f0173bb3322bf560724fd1"},"admin":true,"email":"emaple3#gmail.com","last_login":"10:25:24 AM","name_surname":"user3","password":"qwerty123"}];
you can create a function like bellow
function searchByLastLogin(last_login) {
return users.filter(function(user) {
return user.last_login === last_login;
});
}
console.log(searchByLastLogin("12:25:24 AM"));
console.log(searchByLastLogin("10:25:24 AM"));
console.log(searchByLastLogin("11:25:24 AM"));
It will retrun a array of users whose last_login will match to given parameter last_login.
Update
What I understood from your comment bellow, you want last logins of every user.
For that you can do something like bellow
var last_logins = users.map(function(user){
return user.last_login;
});
console.log(last_logins); //prints [ '11:25:24 AM', '12:25:24 AM', '10:25:24 AM' ]
References
filter | map
I don’t know what value to put in the find() inside the curly braces this is the part where I am stuck
If I understand correctly, you only want to get the last_login field for the user model, and that's what you're struggling with ?
According to the documentation, this should work if you only want to get that field :
User.find({}, {last_login:1, _id:0})
I'm looking into adding full text search to a Meteor app. I know MongoDB now supports this feature, but I have a few questions about the implementation:
What's the best way to enable the text search feature (textSearchEnabled=true) in a Meteor app?
Is there a way to add an index (db.collection.ensureIndex()) from within your app?
How can you run a Mongo command (i.e. db.quotes.runCommand( "text", { search: "TOMORROW" } )) from within a Meteor app?
Since my goal is to add search to Telescope, I'm searching for a "plug-and-play" implementation that requires minimal command line magic and could even work on Heroku or *.meteor.com.
The simplest way without editing any Meteor code is to use your own mongodb. Your mongodb.conf should look something like this (on Arch Linux it is found at /etc/mongodb.conf)
bind_ip = 127.0.0.1
quiet = true
dbpath = /var/lib/mongodb
logpath = /var/log/mongodb/mongod.log
logappend = true
setParameter = textSearchEnabled=true
The key line is setParameter = textSearchEnabled=true, which, as it states, enables text search.
Start mongod up
Tell meteor to use your mongod not its own by specifying the MONGO_URL environmental variable.
MONGO_URL="mongodb://localhost:27017/meteor" meteor
Now say you have collection called Dinosaurs declared say in collections/dinosaurs.js
Dinosaurs = new Meteor.Collection('dinosaurs');
To create an text index for the collection create a file server/indexes.js
Meteor.startUp(function () {
search_index_name = 'whatever_you_want_to_call_it_less_than_128_characters'
// Remove old indexes as you can only have one text index and if you add
// more fields to your index then you will need to recreate it.
Dinosaurs._dropIndex(search_index_name);
Dinosaurs._ensureIndex({
species: 'text',
favouriteFood: 'text'
}, {
name: search_index_name
});
});
Then you can expose the search through a Meteor.method, for example in the file server/lib/search_dinosaurs.js.
// Actual text search function
_searchDinosaurs = function (searchText) {
var Future = Npm.require('fibers/future');
var future = new Future();
Meteor._RemoteCollectionDriver.mongo.db.executeDbCommand({
text: 'dinosaurs',
search: searchText,
project: {
id: 1 // Only take the ids
}
}
, function(error, results) {
if (results && results.documents[0].ok === 1) {
future.ret(results.documents[0].results);
}
else {
future.ret('');
}
});
return future.wait();
};
// Helper that extracts the ids from the search results
searchDinosaurs = function (searchText) {
if (searchText && searchText !== '') {
var searchResults = _searchEnquiries(searchText);
var ids = [];
for (var i = 0; i < searchResults.length; i++) {
ids.push(searchResults[i].obj._id);
}
return ids;
}
};
Then you can publish only documents that have been searched for in 'server/publications.js'
Meteor.publish('dinosaurs', function(searchText) {
var doc = {};
var dinosaurIds = searchDinosaurs(searchText);
if (dinosaurIds) {
doc._id = {
$in: dinosaurIds
};
}
return Dinosaurs.find(doc);
});
And the client side subscription would look something like this in client/main.js
Meteor.subscribe('dinosaurs', Session.get('searchQuery'));
Props to Timo Brinkmann whose musiccrawler project was the source of most this knowledge.
To create a text index and try to add like this I hope so it will be useful if there is still problem comment
From docs.mongodb.org:
Append scalar index fields to a text index, as in the following
example which specifies an ascending index key on username:
db.collection.ensureIndex( { comments: "text",
username: 1 } )
Warning You cannot include multi-key index field or geospatial index
field.
Use the project option in the text to return only the fields in the
index, as in the following:
db.quotes.runCommand( "text", { search: "tomorrow",
project: { username: 1,
_id: 0
}
}
)
Note: By default, the _id field is included in the result set. Since the example index did not include the _id field, you must
explicitly exclude the field in the project document.
I would like to achieve something like this:
filteringSelect.query = {id: "12|13"};
or
filteringSelect.query = {id: new RegExp("12|13")};
Is it possible?
I am using ItemFileReadStore as a store for that FilteringSelect.
See Fuzzy Matches on dijit.form.ComboBox / dijit.form.FilteringSelect Subclass if you want to go the extra mile. This is however for filtering user-input.
For filtering away entries before opening/entering anything in the filteringSelect, continue what youre doing allready. A simple string will not accept the OR operator though, use RegExp.
ItemFileReadStore docs on query
var store = new ItemFileReadStore( {
query: {
id: new RegExp("/^(12|13)$/")
}
} );
As a starting point, ALL items are present in the store, the way to make use of the queryengine is through fetch
store.fetch({
query: {
// yes, you can set the query property directly
// in the store and leave out this parameter
id: new RegExp("^(1|12)$")
},
onComplete: function(items) {
dojo.forEach(items, function(item) {
console.log(store.getValue(item, 'name'))
});
}
})
See http://jsfiddle.net/LuUbT/ for example usage