How to map Grails domain object to a specific mongodb table name - mongodb

I've setup a simple grails app looking at a mongodb.
My domain object looks like this:
class GoogleSearch {
String _id;
String id;
String query;
String site;
Object results;
Date date;
static mapping = {
table 'google_searches'
}
static constraints = {
}
}
However when I run the grails app up, it keeps reading/writing to a table named "googleSearch"
Does anyone know how I can override this default naming? Is it a gorm/mongodb thing?
Cheers

Basics of MongoDB. There is no concept of table. It is always collections. :)
Refer mapping as collection 'google_searches'.
For more details you can refer Grails MongoDB plugin.

Related

Grails GORM hasMany association inconsistent with MongoDB, When try to fetch child Records,it fetches the record sometimes and doesn't fetch sometimes

Below is the domain class Author which has a one-to-many association with Book. When trying to fetch Author, sometimes will get the associated collection of Book domain object and sometimes returns null. Any thoughts on why it is inconsistent?
class Author {
static mapWith = "mongo"
String name
static hasMany = [books: Book]
}
_author.gson
model {
Author author
}
json g.render(author]) {
books g.render(author.books)
}
Environment details:
grailsVersion=3.3.5
gormVersion=6.1.8.RELEASE
We are using GORM multi-tenancy and using MongoDB database.
I have switched to sub-document model and it's working now. Here is the domain model code.
class Author {
static mapWith = "mongo"
String name
List<Books> book
static embedded = ['book']
}

Spring Data - Mongo DB - #TextIndexed over #DBRef

Is it possible somehow to search in String fields over #DBRef.
I have this #Document:
public class DocumentFileVersion {
#TextIndexed
#DBRef
private OtherObject otherObject
and I will search in String fields of otherObject. Is there any possibility to do that?
DBRef are designed to be queried by id reference only.
So it is not possible. You should rethink your schema structure.

Using java.util.Set domain property with Grails 3.1.x and Mongo 5.0.x plugin

I'm trying to create an embedded collection in a Grails GORM Mongo domain class.
class User {
String name
Set<String> friends = []
}
I want to store a Set (a non-duplicated list) of other names of users.
When I try to save the User domain class:
new User(name: 'Bob').save(failOnError: true)
I get the error.
org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for interface java.util.Set.
Changing the Set to List works fine but I don't want duplicates and don't want to have to manage that with a List.
Is there a way GORM will use the underlying Mongo $addToSet functionality.
It might be a GORM MongoDB issue. You can create an issue here with reproducing the issue.
But for now, you can do the workaround this problem using the List like this:
class User {
String name
List<String> friends = []
void removeDuplicate() {
this.friends?.unique()
}
def beforeInsert() {
removeDuplicate()
}
def beforeUpdate() {
removeDuplicate()
}
}

How can I query to find mongo entities whose list of sub-entities contain a field matching a string?

I have a collection of entities that look like this:
public class ClientEntity {
#Id
private String id;
#Indexed(unique = true)
private String clientId;
private String name;
#DBRef
private List<ClientMachineEntity> machines;
...
}
...where ClientMachineEntity looks like:
public class ClientMachineEntity {
#Id
private String id;
#Indexed(unique = true)
private String clientMachineId;
private String hostName;
...
}
I have a working search that finds ClientEntities by matching against "clientId" and "name":
public List<ClientEntity> searchByIdAndName(String id, String name) {
Criteria idCriteria = Criteria.where("clientId").regex(id, "i");
Criteria nameCriteria = Criteria.where("name").regex(name, "i");
Query query = new Query(new Criteria().orOperator(idCriteria, nameCriteria));
...
}
So my question is, how can I expand this search so that it also matches against "clientMachineId" in the list of sub-entities? I tried adding the following criteria:
Criteria machineCriteria = Criteria.where("machines.clientMachineId").regex(id, "i");
...but that doesn't work, presumably because machines is a LIST of entities, not just a single sub-entity.
UPDATE: It seems like what I'm looking for is the .elemMatch() functionality, but when I try that:
Criteria machineCriteria = Criteria.where("machines").elemMatch(Criteria.where("clientMachineId").regex(id, "i"));
...I get the following error:
org.springframework.data.mapping.model.MappingException: No mapping metadata found for class com.mongodb.BasicDBObject
You can't query by fields in subentities linked with DBRef. If ClientMachineEntity would be embedded in ClientMachine - then you could use dot notation or $elemMatch depending on needs.
In your particular example - couldn't field ClientMachineEntity.clientMachineId be saved as _id and used as a primary key? Then you could get the results you need - take a look at: How to query mongodb with DBRef
My suggestion for development with Spring Data MongoDB is - first learn how to (and if it's possible) do it in plain Javascript with MongoDB console, then learn how to do the same with Spring Data MongoDB.

how to create a classes from mogodb

Can someone give me an example of code for mapping with morphia and mongodb?
This is my class which contains database fields. I don't know how to
make the connection between morphia and mongodb.
import com.google.code.morphia.annotations.*;
//#Entity
//define the name of the collection where this entity will be stored
#Entity("tabes")
class MappingMorphia {
#Id
String id;
String FACILITY;
String HOST;
String MESSAGE;
String PID;
String PRIORITY;
String PROGRAM;
int SEQNUM;
String SOURCE;
String SOURCEIP;
String TAGS;
//getters and setters
}
There are examples aplenty at the morphia github site: https://github.com/mongodb/morphia/wiki
Mongodb doesn't understand about classes as is, or at least not the way you are thinking. There is, however, a module called mongoose that lets your model your objects. I think that will suit you.
Here's a link to mongoose's docs
http://mongoosejs.com/docs/documents.html