Here is my database schema:
Database name: user
_id 74acd65e6eeb6d55809a950036000f50
_rev 1-f5ca343d0688d7a01b549e5c29a4a911
Budget dsds
user_Id abc123
Name ssdsd
Now what I want is to retrieve all the records who are having "user_Id":"ssdsd" using GWT.
Like in mysql: select * from user where user_Id=ssdsd
Please guide me in the following code
public String view(String user_id) throws IllegalArgumentException {
// TODO Auto-generated method stub
Session s1=new Session("127.0.0.1",5984);
Database db=s1.getDatabase("users");
return "";
Unfortunately I'm not familiar with GWT, but I think your question is more CouchDB-related.
If you plan on having one and exactly one document per user, then you should use the user_Id directly as the _id. This way you get the benefit of using the "primary" index of CouchDb to your advantage and enforce unique user ids at the same time.
It is good practice and a convention to also store the type of the document in the type property.
The document could look like this:
{
"_id": "user.abc123",
"type": "user",
"name": "ssdsd",
"budget": "dsds"
}
If you need to have multiple documents per user_Id, then you need to write a CouchDB view. You can read an introduction in the CouchDB Docs.
This would be some simple JavaScript code for the CouchDB map function:
function (doc) {
if (doc.user_Id) {
emit(doc.user_id, {budget: doc.budget});
}
}
You would then be able to query this view by calling the view with a key of "abc123", e.g. in the browser by calling this URL:
http://localhost:5984/users/_design/users/_view/users?key=[“abc123"]
P.S.: If you need authentication also, it might be worth considering to store the users in the built-in database _users. Just keep in mind that there are some restrictions in this system db: non-admins cannot read other users' documents in this db, and some special schema requirements have to be met when adding documents there.
Related
How can I find a document and retrieve it if found, but insert and retrieve it if not found in one command?
I have an outline for the formats I wish my documents to look like for a user's data. Here is what it looks like
{
"username": "HeyAwesomePeople",
"uuid": "0f91ede5-54ed-495c-aa8c-d87bf405d2bb",
"global": {},
"servers": {}
}
When a user first logs in, I want to store the first two values of data (username and uuid) and create those empty values (global and servers. Both those global and servers will later on have more information filled into them, but for now they can be blank). But I also don't want to override any data if it already exists for the user.
I would normally use the insertOne or updateOne calls to the collection and then use the upsert (new UpdateOptions().upsert(true)) option to insert if it isn't found but in this case I also need to retrieve the user's document aswell.
So in a case in which the user isn't found in the database, I need to insert the outlined data into the database and return the document saved. In a case where the user is found in the database, I need to just return the document from the database.
How would I go about doing this? I am using the latest version of Mongo which has deprecated the old BasicDBObject types, so I can't find many places online that use the new 'Document' type. Also, I am using the Async driver for java and would like to keep the calls to the minimum.
How can I find a document and retrieve it if found, but insert and retrieve it if not found in one command?
You can use findOneAndUpdate() method to find and update/upsert.
The MongoDB Java driver exposes the same method name findOneAndUpdate(). For example:
// Example callback method for Async
SingleResultCallback<Document> printDocument = new SingleResultCallback<Document>() {
#Override
public void onResult(final Document document, final Throwable t) {
System.out.println(document.toJson());
}
};
Document userdata = new Document("username","HeyAwesomePeople")
.append("uuid", "0f91ede5")
.append("global", new Document())
.append("servers", new Document());
collection.findOneAndUpdate(userdata,
new Document("$set", userdata),
new FindOneAndUpdateOptions()
.upsert(true)
.returnDocument(ReturnDocument.AFTER),
printDocument);
The query above will try to find a document matching userdata; if found set it to the same value as userdata. If not found, the upsert boolean flag will insert it into the collection. The returnDocument option is to return the document after the action is performed.
The upsert and returnDocument flags are part of FindOneAndUpdateOptions
See also MongoDB Async Java Driver v3.4 for tutorials/examples. The above snippet was tested with current version of MongoDB v3.4.x.
I know it is a non-relational database but this does not mean that relational data does not exist.
For example, I have a table that holds urls like this ( simplified ):
url | domain
and I have a table that holds domains like this ( simplified ):
domain | favicon_path
Because many different urls may have the same domain, I did not want to repeat the favicon_path for each domain when pulling the data for sending to the view.
Hence I used a simple ( simplified for example ) join command when I need the data.
"SELECT bookmarks.*, domains.favicon FROM bookmarks JOIN
domains ON bookmarks.domain=domains.domain"
How would I handle this scenario using no-sql?
I plan on implementing no-sql using indexedDB on the client ( javascript ) and MongoDB on the server ( java ).
If you want to use document-oriented DB, you can use this structure of documents:
URL_ID : {
"domain":"id_of_domain",
"another_staff": "..."
}
DOMAIN_ID : {
"favicon_path" : "path or id of another document",
"another_staff": "..."
}
So you can get document with URL_ID by id from database and then get document of type Domain.
ADDITION:
You can use the following approach for generating id. Create special document (like sequence) which will have only one field - current_value_of_sequence. Every insert to DB you have to get this sequence and increment it. Some DB like Couchbase have low-level support of this mechanism, which very efficient and thread-safety.
From years of work expierence in IT area, I would say most of the business models could be normalized as simple as these two types of data structure:
Entity info.
Entity list.
For example, in a book store business, we will have the Book entity, and many list that containing all of the books or a subset of the whole books.
With a NoSQL database, such as Redis or SSDB, the Book entity is stored with Key-Value, where key is the book sn, and value is the stringified book info(title, publish date, description, etc). While book list(list by publish date, list by price, etc) are stored in zset data type.
I am working in a Spring web application using Cassandra with Astyanax client. I want to transform result data retrieved from Cassandra queries to a POJO, but I do not know which library or Astyanax API support this.
For example, I have User column family (CF) with some basic properties (username, password, email) and other related additional information can be added to this CF. Then I fetch one User row from that CF by using OperationResult> to hold the data returned, like this:
OperationResult<ColumnList<String>> columns = getKeyspace().prepareQuery(getColumnFamily()).getRow(rowKey).execute();
What I want to do next is populating "columns" to my User object. Here, I have 2 problems and could you please help me solve this:
1/ What is the best structure of User class to hold the corresponding data retrieved from User CF? My suggestion is:
public class User {
String userName, password, email; // Basic properties
Map<String, Object> additionalInfo;
}
2/ How can I transform the Cassandra data to this POJO by using a generic method (so that it can be applied to every single CF which has mapped POJO)?
I am so sorry if there are some stupid dummy things in my questions, because I have just approached NoSQL concepts and Cassandra as well as Astyanax for 2 weeks.
Thank you so much for your help.
You can try Achilles : https://github.com/doanduyhai/achilles, an JPA compliant Entity Manager for Cassandra
Right now there is a complete implementation using Thrift API via Hector.
The CQL3 implementation using Datastax Java Driver is in progress. A beta version will be available in few months (July-August 2013)
CQL3 is great but it's still too low level because you need to extract the data yourself from the ResultSet. It's like coming back to the time when only JDBC Template was available.
Achilles is there to fill the gap.
I would suggest you to use some library like Playorm using which you can easily perform CRUD operations on your entities. See this for an example that how you can create a User object and then you can get the POJO easily by
User user1 = mgr.find(User.class, email);
Assuming that email is your NoSqlId(Primary key or row key in Cassandra).
I use com.netflix.astyanax.mapping.Mapping and com.netflix.astyanax.mapping.MappingCache for exactly this purpose.
I've started to fiddle with mongo db and came up with a question.
Say, I have an object (POJO) with an id field (say, named 'ID') that I would like to represent in JSON and store/load in/from Mongo DB.
As far as I understood any object always has _id field (with underscore, lowercased).
What I would like to do is: during the query I would like the mongo db to return me my JSON with field ID instead of _id.
In SQL I would use something like
SELECT _id as ID ...
My question is whether its possible to do this in mongo db, and if it is, the Java based Example will be really appreciated :)
I understand that its possible to iterate over the records and substitute the _id with ID manually but I don't want this O(n) loop.
I also don't really want to duplicate the lines and store both "id" and "_id"
So I'm looking for solution at the level of query or maybe Java Driver.
Thanks in advance and have a nice day
Mongodb doesnt use SQL , its more like Object Query Language and Collections.
what you can try is , some thing similar to below code using Mongo Java Driver
Pojo obj = new PojoInstance();
obj.setId(id);
db.yourdb.find(obj);
I've end up using the following approach in the Java Driver:
DBCursor cursor = runSomeQuery();
try {
while(cursor.hasNext()) {
DBObject dbObject = cursor.next();
ObjectId id = (ObjectId) dbObject.get("_id");
dbObject.removeField("_id");
dbObject.put("ID", id.toString());
System.out.println(dbObject);
}
} finally {
cursor.close();
}
I was wondering whether this is the best solution or I have other better options
Mark
Here's an example of what I am doing in Javascript. It may be helpful to you. In my case I am removing the _id field and aliasing the two very nested fields to display simpler names.
db.players.aggregate([
{ $match: { accountId: '12345'}},
{ $project: {
"_id": 0,
"id": "$id",
"masterVersion": "$branches.master.configuration.player.template.version",
"previewVersion": "$branches.preview.configuration.player.template.version"
}
}
])
I hope you find this helpful.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Mongodb database Schema Design with shared data
Hi I am newbie to mongodb.I am using java.
I have 4 tables Tenant,system,authorization in my relational table.
Something like this.
Table Fields
Tenant Tenant_ID(PK), Tenant_INFO
System System_ID(PK), System_Info
Authorization System_ID, Autho_Info.
System_prop System_ID, Prop_Info, Tenant_ID
In System_prop table, Tenant_ID refers the Tenant Table Tenant_ID (PK), System_ID refers the System Table System_ID.
In Authorization table, System_ID refers System tabel System_ID
I am switching my database from relational to mongodb. First thing I need to do is Schema design.
Query I need to do is:
SELECT D.Prop_Info, D.System_ID, A.Tenant_Info From TENANT A ,System_prop D, SYSTEM B, Where D.System_ID = B.System_ID AND D.Tenant_ID = A.Tenant_ID
SELECT C.System_ID, C.auth_Info, B.System_ID FROM Authorization C, SYSTEM B WHERE C.System_ID = B.System_ID
Can anyone help me how to design these tables as collections in mongodb?
Do i need to embed r use dbref? Help me to design the schema for this.
From the schema information you provided, it looks like you have a many-to-many relationship between Tenant and System (through the JOIN table System_prop), and a one-to-many relationship between System and Authorization.
In MongoDB, both of these types of relationships can be implemented using array fields. This is how you could set up your System collection:
{
System_Info: ...,
Tenant: [
{
Tenant_Id: ...,
Tenant_Info: ...,
Prop_Info: ...
},
{
Tenant_Id: ...,
Tenant_Info: ...,
Prop_Info: ...
} ],
Authorization: [
{
Auth_Id: ...,
Auth_Info: ...
},
{
Auth_Id: ...,
Auth_Info: ...
} ]
}
However, for the Tenant info, you will now have de-normalized duplicate information, i.e. the same Tenant document appears in different System documents. It is up to your application to ensure consistency.
As for the queries you mentioned: It looks like there is some information missing. For the first query, you're joining on the Tenant_Id but not requesting any information from the Tenant table. The second one requests Prop_Info from the Authorization table but that table doesn't have Prop_Info. Should that be A.Autho_Info instead? So you might want to double-check these queries.
Here are some additional resources about schema design in MongoDB that are worth a read:
http://www.mongodb.org/display/DOCS/Schema+Design
https://openshift.redhat.com/community/blogs/designing-mongodb-schemas-with-embedded-non-embedded-and-bucket-structures
In the end, it depends on your application and most frequent queries how exactly you choose to store your data, and the example above is just one way to set up your schema.
You are still thinking in relational databases. MongoDB, however, is a document-oriented database.
artificial ID numbers are usually not needed, because every document automatically has a _id field, which is a GUID (as good as guaranteed to be globally unique).
relation tables should not be used in MongoDB. n-type relations are made with arrays fields instead. So when 1 system has N authorizations it uses, your system document should have a field "authorization" which is an array of the object IDs of the authorizations it has. Yes, that would be a horrible violation of the normalization rules of relational databases. But you don't have a relational database here. In MongoDB it is practical to represent N-relations with arrays, because arrays are transparent to the query language.