Finding the number of different values of an attribute - mongodb

I am writing an APS.NET MVC 5 application in C#, using a MongoDB database. Suppose I have a MongoDatabase object called my_db, which contains a MongoCollection of Label objects, called labels. Each Label object has a few attributes, one of which is a string called tag. Each tag value may be shared across different Labels, such that some Label objects will have the same value for tag.
I want to find out how many different values for tag there are in this collection, and store these values in an array of some sort.
I'm fairly new to MongoDB, so I don't really know how to do this. All I have done so far is get labels:
var labels = my_db.GetCollection<Label>("labels");
But I'm stuck as to what I need to do now. I could manually iterate through each Label in labels, and check whether that Label's tag attribute has already been seen before. But is there a neater way to do this with a MongoDB function? Thanks!

There is a MongoDB method for this: distinct, that should exist in any API.

As you are doing this on MVC 5 c# application, MongoDB provides C# LINQ Driver which will help your querying MongoDB using LINQ.
http://docs.mongodb.org/ecosystem/tutorial/use-linq-queries-with-csharp-driver/
Hope this helps.
var query = (from e in labels.AsQueryable<labelClass>()
select e.tag).Distinct()

Related

Laravel in controller return new collection of results from a foreach loop through records

This seems like it should be obvious, but everything I find relates to returning a collection extracted from records, rather then returning a collection of new results derived from calculations on the records.
For instance, say I have records of property in my database. I can extract a collection of a subset (or the entire set) of the records. But I want to loop through this collection, calculate new values for each line item, (like marketValue-debt=netValue) and return a new collection of just those results to my view. I'm trying to keep my (much more complicated than this example) calculation in my controller and out of my view, but I'm not getting the way to stuff new values into a new collection of results for return to display in the view.
I could derive my results and stuff them into an array, but how do I pass this as a new collection for looping through in my view to show those results? Seems like there should be an Eloquent way to do this.
My project is in Laravel 6 running on Apache/Laragon, PHP 7 with MariaDb
Thanks in advance for helping me out.
Take a look at this. Hope it will be of some help.
If you want a new collection, use the map method.
$new_collection = $old_collection->map(function ($item) {
return $item->marketValue - $item->debtValue;
});

Build couchbdb view to index all documents whose ID starts with various three or four characters?

I'm new to nosql and views. Wondering if someone could show me how to build an index such that it will return all the different documents that apply multiple different keys. An example is below.
I have many many documents that all have the naming convention as follows:
AABA_August-11-2017_2017-06-29_10
BBY_August-11-2017_2017-06-29_10
CECO_January-19-2018_2017-06-08_19
GEL_December-15-2017_2017-06-08_1
Etc..
I'd like a view such that I could query on "starts with BBY" for example. And it would return all the documents that start with BBY. Maybe even "BBY_December", "BBY_August" etc.
Wondering if this is possible and what it would look like. I'm using CouchDB which uses Mango to build indexes. If someone could just point me in the right direction that would help too.
Thanks
You could write such a view like this:
function(doc) {
var docId = doc._id;
var p = docId.substring(0, 2); // Or however many chars you want
if (p === 'BBY') emit(doc._id, doc); // Or whatever kind of key you want
}
And then write similar views for alternate prefixes. You can also use query parameters similar to the _all_docs endpoint with views (http://docs.couchdb.org/en/2.0.0/api/ddoc/views.html).
I think the only benefit of using a view instead of what you have done is that you can filter unnecessary fields, do some basic transformations, etc.
Considering the similarities between retrieval from _all_docs vs from a view, it looks like the _all_docs endpoint is just index similar to a custom view. But I'm not sure on that.
Not sure how to use Mango to do the same.
My current naming convention required no new index. I used futon to find:
ip:port/DB/_all_docs?inclusive_end=true&start_key="BBY_Aug"&end_key="BBY_Auh"

How to change live date?

I wonder, How do I change a live data schema with MongoDB ?
For example If I have "Users" collection with the following document:
var user = {
_id:123312,
name:"name",
age:12,
address:{
country:"",
city:"",
location:""
}
};
now, in a new version of my application, if I add a new property to "User" entity, let us say weight, tall or adult ( based on users year ), How to change all the current live data which does not have adult property. I read MapReduce and group aggregation command but, they seem to be comfortable and suitable for analytic operation or other calculations, or I am wrong.
So what is the best way to change your current running data schema in MongoDB ?
It really depends upon your programming language. MongoDB is really good at having a dynamic schema. I think your pattern of thought at the moment is too SQL related whereby you believe that all rows, even if they do not yet have a value, must have the new field.
The reality is quite different. The rows which have nothing meaningful to put into them do not require the field and you can, in your application, just check to see if the returned document has a value, if not then you can assume, as in a fixed SQL schema, that the value is null.
So this is one aspect where MongoDB shines, is the fact that you don't have to apply that new field to the entire schema on demand, instead you can lazy fill it as data is entered by the user.
So just code the field into your application and let the user do the work for you.
The best way to add this field is to write a loop, in maybe the console close or on the primary of your replica (if you have one, otherwise just on the server), like so:
db.users.find().forEach(function(doc){
doc.weight = '44 stone';
db.users.save(doc);
});
That is currently the best way to do something like what your asking.

How to order documents by a dynamic property in Mongoid

I am using Mongoid to store a series of geocoded listings. These listings need to be sorted by price and proximity. The price of every listing is a field in the database whereas distance is a dynamic property that is unique for every user.
class Listing
include Mongoid::Document
field :price
def distance
get_distance(current_user.location,coordinates)
end
end
How can I sort these documents by distance? I tried #listing.desc(:distance) and that didn't work.
The short (and unhelpful) answer is: you can't.
Mongoid does have the ability to query based on 2d co-ordinates though, then you could update your controller to do something like this:
#listings = Listing.near(current_user.location)
Which I believe will return your listings in order of distance.
On a side note, I noticed that your Listing model is referring to your current_user object, which kinda breaks the MVC architecture, since your models shouldn't know anything about the current session.

coldfusion - bind a form to the database

I have a large table which inserts data into the database. The problem is when the user edits the table I have to:
run the query
use lots of lines like value="<cfoutput>getData.firstname#</cfoutput> in the input boxes.
Is there a way to bind the form input boxes to the database via a cfc or cfm file?
Many Thanks,
R
Query objects include the columnList, which is a comma-delimited list of returned columns.
If security and readability aren't an issue, you can always loop over this. However, it basically removes your opportunity to do things like locking certain columns, reduces your ability to do any validation, and means you either just label the form boxes with the column names or you find a way to store labels for each column.
You can then do an insert/update/whatever with them.
I don't recommend this, as it would be nearly impossible to secure, but it might get you where you are going.
If you are using CF 9 you can use the ORM (Object Relation Management) functionality (via CFCs)
as described in this online chapter
https://www.packtpub.com/sites/default/files/0249-chapter-4-ORM-Database-Interaction.pdf
(starting on page 6 of the pdf)
Take a look at <cfgrid>, it will be the easiest if you're editing table and it can fire 1 update per row.
For security against XSS, you should use <input value="#xmlFormat(getData.firstname)#">, minimize # of <cfoutput> tags. XmlFormat() not needed if you use <cfinput>.
If you are looking for an easy way to not have to specify all the column names in the insert query cfinsert will try to map all the form names you submit to the database column names.
http://help.adobe.com/en_US/ColdFusion/9.0/CFMLRef/WSc3ff6d0ea77859461172e0811cbec22c24-7c78.html
This is indeed a very good question. I have no doubt that the answers given so far are helpful. I was faced with the same problem, only my table does not have that many fields though.
Per the docs EntityNew() the syntax shows that you can include the data when instantiating the object:
artistObj = entityNew("Artists",{FirstName="Tom",LastName="Ron"});
instead of having to instantiate and then add the data field by field. In my case all I had to do is:
artistObj = entityNew( "Artists", FORM );
EntitySave( artistObj );
ORMFlush();
NOTE
It does appear from your question that you may be running insert or update queries. When using ORM you do not need to do that. But I may be mistaken.