I have some problems to understand nosql. Im using mongodb and java and would like to create something like that: a table (persons) with a column for name (as string), age (as integer), married (boolean). In a normal sql it would be easy... but how to go on with mongodb and java?
Ok stuff I know: a table in mongodb is a collection and a column is a BSON field. I would start like this
Mongo m = new Mongo();
DB db = m.getDB("myDatabase");
DBCollection col = db.getCollection("Persons");
BasicDBObject doc = new BasicDBObject();
doc.put("something?", "something?");
col.insert(doc);
the first 3 steps are easy. I have my collection (table), I should make the BSON fields (columns) name, age, married. But how? I know the put() method, but what should I put in? And if I have the construct, I would like to add some "persons".
Any ideas? Thank you
You should try to get rid of thinking about columns with MongoDB. It is schemaless so every document may have different set of fields even in same collection so thinking fields are columns may be misleading.
I recommend going through the official MongoDB Java tutorial HERE.
You should be able to do something like this:
doc.put("name", "John");
doc.put("age", 30);
doc.put("married", false);
Taking a look at the documentation here:
http://api.mongodb.org/java/2.0/org/bson/BasicBSONObject.html#put(java.lang.String, java.lang.Object)
It seems to me that put accepts key and value for one of your fields, for instance:
doc.put("name", myPersonInstance.getName());
doc.put("age", myPersonInstance.getAge());
You can insert as many attributes using put as you want. There's also methods to add from a Map and such.
Please keep in mind I've never used the MongoDB Java API, so I'm basing my statements solely on that documentation and some slight knowledge of MongoDB in general.
For the record, those "put's" would be equivalent to a JSON structure like:
{name: "John", age:35}
Hope it helps.
Related
I have two basic document types:
Patient with fields name and number;
Analysis with fields that
consist of 3 arrays, date of analysis, a bunch of floats and a
patientId, linking it to the Patient, so there's a 1:M relationship
between Patient and Analysis.
I'm using Ektorp as a driver. Right now there are two POJOs, reflecting the documents, and Patient POJO also has a Set<Analysis>, marked by #DocumentReferences annotation (which I don't actually need yet, but might use later to show all analyses for one patient, for example).
However, what I want to do is use pagination to populate TableView with rows, containing info about both Patient AND Analysis, sorted by date of analysis in descending order.
Right now, my only idea is to
Query CouchDB for all Analysis documents sorted by date (using
pagination via PageRequest in Ektorp)
Then for each analysis query db for patients with patientId
Make a separate class representing a row in table with fields for both patient and analysis, then create an object of that class using
retrieved Analysis and Patient objects.
In code it would look somewhat like this:
PageRequest pageRequest = PageRequest.firstPage(5);
ViewQuery query = new ViewQuery()
.designDocId("_design/analysis")
.viewName("by_date")
.descending(true)
.includeDocs(true);
Page<Analysis> result = db.queryForPage(query, pageRequest, Analysis.class);
for(Analysis analysis : result) {
Patient patient = db.find(Patient.class, analysis.getPatientId());
Row row = new Row(patient, analysis);
//TODO: ...Populate TableView...
}
This all sounds very cumbersome. Is there a better way to do this? Can I deserialize data I need in one go (or at least in one query)?
I know there's a way to use {_id: doc.patientId} as a value in emit() function to return Patient for each Analysis when querying with parameter include_docs=true, but I'm not sure how to use that to my advantage.
I could just embed Patient in Analysis, but then I would have to change every Analysis document if there's a change in Patient, so that's not a good solution.
I've read these two paragraphs of documentation several times over, but I can't for the life of me figure out how to implement them with Ektorp.
Any help would be appreciated.
So I am exploring how to query mongo from java, and I found several different ways of querying this, and I'm not sure if I'm missing some nuance, thus not fully understanding the queries, or they are the same.
So far I found, for java driver v3.2, this:
collection.find().projection(fields(include("x", "y"), excludeId()))
And I've been told this should work:
BasicDBobject query = new BasicDBObject("x", x).append("y", y);//This example may not compile, I haven't tried it, I'm more talking about the idea and concept.
This query would go with a find(), findOne(), distinct(), and so on.
String fields = "averageSpeed";
coll = db.getCollection(strMongoCollection);
coll.find(fields, query));
So, are both right approaches? Or its purpose is deferent
You always have the option of using the old unwieldy Bson objects yourself, but for the 3.2 driver I'd rather go with the Filters and Projections helper classes.
Thus, a simple search with some criteria can be sent as
collection.find(Filters.eq("myfield", "myvalue"))
For selecting certain fields only, you append a projection:
collection.find(Filters.eq("myfield", "myvalue"))
.projection(Projections.include("myfield", "anotherfield"))
Apart from the more elegant code of the new API, the queries do the same as the BasicDBObject-based calls.
I already used the search here (and other forums as well) but haven't found an answer exacty to what I'm trying to do.
I know that it can easily be done in some other way, and this is just a small sandbox-framework I'm coding for a University course... in a real environment I'd just take Spring, Hibernate etc.
So what I did was coding myself a small generic Data Access Layer with POJOs, working with generic methods to retrieve, check or insert data to the database (Oracle). Most of this is done through PreparedStatements.
This is working as long as I don't have joins... is it possible to put in a Column as parameter?
Example:
Table A has Attribute X + others
Table B has Attribute Y + others
PreparedStatement with query SELECT * FROM A,B WHERE "A"."X" = ?
And then fill in "B"."Y" as the parameter...
The database doesn't throw me an error or exception, but the ResultSet returned after executing the statement is empty. Is it just not possible to do, or am I just missing some escaping?
I'm using PreparedStatement.setString(int index, String value) to fill in the parameter... in lack of ideas which other setX method I could use...
Again, in a real project I'd never code that myself, but rather use something like Spring or Hibernate and not re-invent the wheel, but I see it as an interesting exercise to code such a generic small data access layer myself.
No, JDBC does not allow this. Only column values can be set. If you want to make dynamic changes to the sql statement you will have to do it before you create the PreparedStatement.
I am having some difficulty structuring the exact Elasticsearch query that I am looking for, specifically using the java api.
It seems like if I construct a fieldsearch using the java api, I can only use a single field and a single term. If I use a querystring, it looks like I can apply an entire query to a set of fields. What I want to do is apply a specific query to one field, and another query to a different field.
This is confusing I know. This is the type of query I would like to construct
(name contains "foo" or name contains "bar") AND ( date equals today)
I am really loving Elasticsearch for it's speed and flexibility, but the docs on http://www.elasticsearch.org/ are kind of tough to parse (I noticed "introduction" and "concepts" have no links, but the API section does) If anyone has some good resources on mastering these queries, I'd love to see them. Thanks!
Sounds like a bool query with 2 must clause:
matchQuery("name", "foo bar")
rangeQuery("date").from("2013-02-05").to("2013-02-06")
Does it help?
I am working with Java Classes, and I'm looking for the easiest way to connect a DB table in MySQL with the members (attributes) to the Java code.
After executing the "SELECT" query I get a resultSet, yet it is not clear to me how to cast the result Object to the Java Object generically.
For Example: I have 2 Java Classes - Student & Teacher, and I would like to use a command:
Student student = (Student) rs.getObject();
Thanks,
Roi
I would recommend using JPA with eclipselink implementation, rathern than executing queries using plain JDBC, and try to map results from resultsets to objects by hand (error prone). JPA will do that for you !
this doesn't work in that way. You should do something like:
Student st = new Student();
st.setName(rs.getString("NAME"));
st.setAverage(rs.getInt("SCORE"));
where NAME and SCORE are the column names.
The doc can also help you.
You can look at ORM solutions, like Hibernate.
If your question is about rs.getObject.
The call rs.getObject is a generic way of calling rs.getInt, rs.getString because the return values of all these methods are ultimately Objects (Int, String etc...).
It will return the column you ask for (either by order number in the select or by column name). Not the whole bean corresponding to a row.
You use rs.getObject when you do not know at compilation time the type of the returned column.
The JDBC ResultSet Object does not have a magic getObject method that will return the bean corresponding to a select statement.
You can develop your own 'poor man's ORM' with combination of
JBBC ResultSetMetaData
Java Reflexion
But that's a harder work than using an existing one.