Fetching referenced mongodb documents in another collection using Morphia - java

I've been trying to wrap around my head around this...
I have the following referenced documents in a users and groups collection.
group documents
{
"_id" : ObjectId("52eabc9914cc8d6cc1e6f723"),
"className" : "org.xxxxxx.sms.core.domain.Group",
"name" : "CE Play group",
"description" : "CE Play group",
"creationdate" : ISODate("2014-01-30T20:56:57.848Z"),
"user" : DBRef("users", ObjectId("52ea69c714ccd207329b2476"))
}
{
"_id" : ObjectId("52ea69c714ccd207329b2477"),
"className" : "org.xxxxxx.sms.core.domain.Group",
"name" : "Default",
"description" : "Default sms group",
"creationdate" : ISODate("2014-01-30T15:03:35.916Z"),
"user" : DBRef("users", ObjectId("52ea69c714ccd207329b2476"))
}
users document
{
"_id" : ObjectId("52ea69c714ccd207329b2476"),
"className" : "org.xxxxxx.core.domain.User",
"username" : "jomski2009",
"firstname" : "Jome",
"lastname" : "Akpoduado",
"email" : "jomea#example.com",
"active" : true,
"usergroups" : [
DBRef("groups", ObjectId("52ea69c714ccd207329b2477")),
DBRef("groups", ObjectId("52eabc9914cc8d6cc1e6f723"))
]
}
I have a Morphia Datastore singleton object which has been set up in a class to retrieve a user group and perform some manipulations on. Say I wanted to fetch the group named "Default" with a supplied username "jomski2009" , how would I achieve this in Morphia without fetching the usergroups as a list and iterating over the list of groups just to find the group I want?
Thanks.

DBRef is used in Mongo as a client side concept. MongoDB does not do joins so the purpose of DBRef is to hand over to the client a location from which to fetch the required object. This is handled by various client libraries in different ways.
If it is feasible for your application to do so, you might want to take a look at using Embedded Annotation instead of the Reference type. Or at the very least to include a list of usernames in your Group objects in addition to the object references. This will allow you to filter these in queries.
Also it is worthwhile looking at moving any unique identifiers like "username" to the _id field of the document as long as it is always unique. Primary key lookups are always faster.

Related

Diferences between insert, save, update in MongoTemplate (Spring)

I am starting with Spring and MongoDB. I have seen that there are several methods to insert and / or update. I have also read some posts here explaining some concepts. But I don't quite understand them.
Correct me if I'm wrong or if things are missing.
Update (): only updates an object and only works if it has an id.
Upsert (): Makes an Update if the object exists (it must have an id) or inserts it if it does not exist.
Insert (): You don't need an id and add a Document to the collection.
save (): I don't really know the difference with an insert.
If there are more methods that work similarly and that I forgot to mention, I would appreciate if you could explain it as well.
Save
The save method saves the document to collection for the entity type of the given object. When we pass collection name, then document is saved in the specified collection, even if entity is of different type.
`Student ram = new Student(101,"Ram",20);
mongoTemplate.save(ram);
Person newPerson = new Person(102, "Shyam");
mongoTemplate.save(newPerson, "student"); `
After Save
{ "_id" : 101, "name" : "Ram", "age" : 20, "_class" : "com.concretepage.entity.Student" }
{ "_id" : 102, "name" : "Shyam", "_class" : "com.concretepage.entity.Person" }
Insert
To insert a document into MongoDB collection, the MongoTemplate provides insert method. Find the code to insert one document.
Student ram = new Student(1,"Ram",20);
mongoTemplate.insert(ram);
After Insert
{ "_id" : 1, "name" : "Ram", "age" : 20, "_class" : "com.concretepage.entity.Student" }
for more info, Refer below link
https://www.concretepage.com/spring-5/spring-data-mongotemplate

Connecting two DatabaseReferences in Android

I have a firebase realtime database, where for every user i have the ids of the groups, they are member of, stored. I have the names of the groups stored seperately. Now what I'm trying to do is to display the users groups ordered alphabetically by the group name (GroupA, GroupB, GroupH, GroupX, ...). But I can't really figure out, how to connect the two references. Does anyone know a way to do it? I don't think it is possible to filter children based on a list of valid keys in realtime database, there's only equalTo, startAt etc. Or do I have to just load the ids, get the corresponding group names, and order them myself?
Here's my database structure:
"group_profiles" : {
"-MAz5iuen-BpsLWP1TR0" : { //GID
"name" : "GroupA"
},
"-MAkiUQ7UnIttXy0ZgZx" : { //GID
"name" : "GroupB"
}
},
"groups" : {
"iwfcfGR4TNatxwxpqEAx7ycNfT43" : { //UID
"-MAz5iuen-BpsLWP1TR0" : { //GID
"key" : "..."
},
"-MAkiUQ7UnIttXy0ZgZx" : { //GID
"key" : "..."
}
},
...
Or do I have to just load the ids, get the corresponding group names, and order them myself?
That's one way to do it.
The other way is to duplicate the required data from the groups into groups_profiles for the purpose of performing the query. This is common in nosql type databases, and is called "denormalization".

How to handle race-condition (Synchronisation) in Java project using ElasticSearch as persistence

Problem: We have data stored in DB. For example, take a USER object which is stored. CRUD operations can occur on any of the USER.
Is there any efficient way in which I can make these cruds as thread-safe if simultaneous operations come for the same USER.
My Solution
We use a Cache like a concurrent map which will help in holding the lock on specific OID if it is being worked upon.
The issue with this approach is we are having an additional cache, which will be handled in various scenarios like system restart and all.
Is there any other way in which I can achieve this which is much efficient. Anything can be done in persistence layer itself ?
PS: I am not using any Framework.
I think you need to use _seq_no and _primary_term.
You should read the document from the elastic search and retrieve sequence number and primary term:
request:
GET example-index/_doc/FOjCPXdy5uFjy80o4vxPI4kzlRQo
response:
{
"_index" : "example-index",
"_type" : "_doc",
"_id" : "FOjCPXdy5uFjy80o4vxPI4kzlRQo",
"_version" : 2,
"_seq_no" : 1,
"_primary_term" : 1,
"found" : true,
"_source" : {
"data": "text"
}
}
then pass them with your update query:
request:
POST example-index/_update/FOjCPXdy5uFjy80o4vxPI4kzlRQo?if_seq_no=1&if_primary_term=1
{
"doc":{
"data": "updated text"
}
}
so if the other agent updated your document those parameters will change after and you will get error 409:
response:
{
"error" : {
"root_cause" : [
{
"type" : "version_conflict_engine_exception",
"reason" : "[FOjCPXdy5uFjy80o4vxPI4kzlRQo]: version conflict, required seqNo [1], primary term [1]. current document has seqNo [2] and primary term [1]",
"index_uuid" : "GUZKnab3T5aBlzXEuOPI7Q",
"shard" : "0",
"index" : "example-index"
}
],
"type" : "version_conflict_engine_exception",
"reason" : "[FOjCPXdy5uFjy80o4vxPI4kzlRQo]: version conflict, required seqNo [1], primary term [1]. current document has seqNo [2] and primary term [1]",
"index_uuid" : "GUZKnab3T5aBlzXEuOPI7Q",
"shard" : "0",
"index" : "example-index"
},
"status" : 409
}
documentation: elastic.co/optimistic-concurrency-control

What is the best practise in spring rest for coding Id based and name based API

Let us consider the below API.
/school/{schoolId or schoolName}
/school/{schoolId or schoolName}/students/{studentId or studentName}
I have to develop the above API's. What is the best way to achieve this in spring REST? I can simply get the URL path variable as a string and check whether it is an id or name and then process it.
But is there any other better solution for this?
There is an elephant in the room, School Name or Student Name is not unique. So it is not advisable to use it in place of id, else you will burn your hand.
/school/{schoolId or schoolName}
I would split this into 2 end points
1. /schools/{schoolId}
if found, return the school entity
HTTP-200
{
"id" : "id-123",
"name" : "worlds best school ever",
"address" : "123 somestreet, some city, some state"
}
if not found,
HTTP 404 and an empty body
2. /schools?name="worlds best school" (other optional things, like sort by, pagination etc)
if at least one entity found per search criteria
HTTP-200
[
{
"id" : "id-123",
"name" : "worlds best school ever",
"address" : "123 somestreet, some city, some state"
}
]
If NO entity found per search criteria
HTTP-200
[]
/school/{schoolId or schoolName}/students/{studentId or studentName}
This begs a question, does one student belong to more than one school, I don't think so. If that's the case, /school/{schoolId or schoolName} is an unnecessary/redundant information. If so, I would change it as
1. /students/{studentId}
if found
HTTP-200
{
"id" : "studentid-345",
"name" : "Albert Einstein",
"school_id" : "id-123"
}
if not found
HTTP 404 with empty body
2. /students?name="Albert Einstein" (other optional things, like sort by, pagination etc)
If at least one entity found per search criteria
HTTP-200
[
{
"id" : "studentid-345",
"name" : "Albert Einstein",
"school_id" : "id-123"
}
]
If NO entity found per search criteria
HTTP-200
[]

importing mongodb data to solr in optimal way

I have millions of documents in my mongodb database and to implement searching I am using Apache Solr. I googled how to import data from mongodb to solr, but found that there is no straight forward approach using Data Import Handler. So I decided to insert the document into Solr at the same time when I am inserting it into mongoDB using the solr client for Java, SolrJ. My documents are in following format in mongoDB:
{
"_id" : ObjectId("51cc52c9e4b04f75b27542ba"),
"article" : {
"summary" : "As more people eschew landlines, companies are offering technologies like\npersonal cell sites and signal boosters to augment cellphones, Eric A. Taub\nwrites in The New York Times.\n\n",
"author" : "By THE NEW YORK TIMES",
"title" : "Daily Report: Trying to Fix a Big Flaw in Cellphone Technology (NYT)",
"source" : "NYT",
"publish_date" : "Thu, 27 Jun 2013 12:01:00 +0100",
"source_url" : "http://bits.blogs.nytimes.com/feed/",
"url" : "http://news.feedzilla.com/en_us/stories/top-news/315578403?client_source=api&format=json"
},
"topics" : [
{
"categoryName" : "Technology Internet",
"score" : "94%"
}
],
"socialTags" : [
{
"originalValue" : "Cell site",
"importance" : "1"
},
{
"originalValue" : "Cellular repeater",
"importance" : "1"
},
{
"originalValue" : "Technology Internet",
"importance" : "1"
}
],
"entities" : [
{
"_type" : "PublishedMedium",
"name" : "The New York Times"
},
{
"_type" : "Company",
"name" : "The New York Times"
},
{
"_type" : "Person",
"name" : "Eric A. Taub"
}
]
}
I want to do indexing on two fields: 'summary' and 'title' of 'article' array.
So far, what I have learned is putting this entire document into solr does not make sense as it will increase the size of index and make searches slower. So, I decided to store following fields in Solr: 'docId', 'title', 'summary', so while searching in solr I will retrieve only docId and then retrieve other details from mongodb bec it faster than retrieving data from solr bec of analysers, tokenisers and all.
FIRST:
So, I need to maintain a unique field 'docId', shall I use use the default '_id' generated by mongod? But for that the doc has to be inserted first, so that mongod can generate the '_id'. So I need to retrieve the doc after inserting into mongodb, fetch the '_id' then insert in solr the fields 'docId', 'summary' and 'title'. Can this be imroved?
SECOND:
I need to define the schema in solr for this where I have to map fields from mongodb to fields in solr. I have the default instance of solr running, from solr/example/start.jar.
It has a default schema and a default collection called 'collection1'. How can I create my own collection, I cannot find anything in the admin interface for this. I want to create a collection for my project and then write a schema as I have defined above.
Whatever tutorials I have found, they simply add the documents to solr. So do I need to override the default schema?
Note: I am new to Solr, you would have already inferred after reading the question :D So please help!

Categories

Resources