N1QL Ansi join using spring data couchbase on document id - spring

I'm trying to do a join using spring data couchbase.
The documentation has this example
#Document
public class Author {
#Id
String id;
String name;
#N1qlJoin(on = "lks.name=rks.authorName")
List<Book> books;
#N1qlJoin(on = "lks.name=rks.name")
Address address;
...
}
I need to do the same, except my model uses the document key:
#Document
public class Author {
#Id
String id;
String addressId;
//#N1qlJoin(on = "lks.addressId=meta(rks).id") this doesn't work
#N1qlJoin(on = "lks.addressId=rks.id") //nor this
Address address;
...
}

Related

how to return relationship in spring data neo4j

Here's nodeEntity
#Data
#NodeEntity
public class Resource {
#Id
#GeneratedValue
private Long id;
#Property("name")
private String name;
private String code;
#Property("parent_code")
private String parentCode;
private String label;
private Neo4jRelationship relationship;
}
And here's relationship between nodes
#Data
#RelationshipEntity
public class Neo4jRelationship {
#Id
private Long id;
#StartNode
private Resource startNode;
#EndNode
private Resource endNode;
}
I want to query all the relationship satify some condition,
#Query("match p = (a : category_first {name: $name})-[*1..2]-() return p")
List<Neo4jRelationship> getFistCatNode(#Param("name") String name);
but the query return am empty list.
However, if I change the return type to org.neo4j.ogm.model.Result, the query can return normally.
I'm confused why the first way dosen't work. Any help will be grateful

Project embedded document fields after lookup operation

I want to do a join between Timesheet:
#Data
#AllArgsConstructor
#NoArgsConstructor
#Document(collection = TIMESHEET_COLLECTION)
public class Timesheet {
#Id
private ObjectId id;
private ObjectId employeeId;
private LocalDate date;
private String occupationTitle;
private BigDecimal salary;
private List<TimesheetEntry> entries;
}
and Employee (as embedded document):
#Data
#AllArgsConstructor
#NoArgsConstructor
#Document(collection = Employee.EMPLOYEE_COL)
public class Employee {
#Id
private ObjectId id;
private String registry;
private String cpf;
private String firstName;
private String lastName;
private String nickname;
private String phone;
private LocalDate dateOfBirth;
private LocalDate admissionDate;
private EmployeeOccupation occupation;
private EmployeePaymentPreferences paymentPreferences;
private Map<String, String> equipmentPreferences;
private Boolean active;
}
So I have this aggregation query, with match, lookup, unwind and projection operations.
Aggregation aggregation = Aggregation.newAggregation(matchTimesheetFilter(timesheetFilter), lookupEmployee(), unwindEmployee(), projectEmployee());
There are lookup and unwind implementations. I'm unwinding because employee should be a single object, not an array.
private LookupOperation lookupEmployee(){
return LookupOperation.newLookup()
.from("employee")
.localField("employeeId")
.foreignField("_id")
.as("employee");
}
private UnwindOperation unwindEmployee(){
return Aggregation.unwind("employee");
}
It returns successfully a Timesheet document with a embedded Employee document. The point is: I don't want all data from employee. I only want a few fields.
So, I tried to exclude unwanted fields from employee, using my projection operation:
private ProjectionOperation projectEmployee() {
return Aggregation.project().andExclude("employee.nickname", "employee.firstName", "employee.fullName");
}
It didn't work. My embedded employee is still being returned with all fields. However I can successfully exclude fields from Timesheet, if I do something like this:
private ProjectionOperation projectEmployee() {
return Aggregation.project().andExclude("startDate", "endDate");
}
How can I project custom fields from a document embedded through a lookup operation?
i think you need to exclude "employee.nickname", "employee.firstName", "employee.fullName", instead of "nickname", "firstName", "fullName"
Try this:
private ProjectionOperation projectEmployee() {
return Aggregation.project().andExclude("employee.nickname", "employee.firstName", "employee.fullName");
}
i did it this way (not sure if it's right but it works):
private LookupOperation lookupEmployee(){
return LookupOperation.newLookup()
.from("employee")
.localField("employeeId")
.foreignField("_id")
.as("employeeLookup");
}
no unwind used
Aggregation.project().and("employeeLookup.firstName").as("employee.firstName")

mongoDB find in query

I have two entities, course and subject as follows,
#Document(collection = "course")
public class Course implements Serializable {
{
...........
#Field("course_name")
private String courseName;
#Field("subjectIds")
private List<String> subjectIds;
...
}
#Document(collection = "subject")
public class Subject implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private String id;
#Field("subject_name")
private String subjectName;
...................
}
here "Course" contains the list of Ids of Subject.
So , I have a subject Id say ("59ce80a4a2e7f329eccac601"), I need to find all the courses where this subject id will be present in the list of subjectIds property of Course.
Is there any way I can write this in query.
I am using mongorepository of spring
MongoDB native query:
db.course.find({subjectIds: { $elemMatch: { $eq: "59ce80a4a2e7f329eccac601"}}})
A corresponding Spring Data MongoDB Query:
#Query("{'subjectIds': {\$elemMatch: {\$eq: ?0}}}")

Spring data mongoDB: Get the distinct rows with pagination

I have User class like,
#Document(collection = "users")
public class User {
private String id;
private String firstName;
private String lastName;
private String jobTitle;
private String email;
private String phoneNumber;
}
And UserDimension as,
#Document(collection = "userDimensions")
public class UserDimension{
private String id;
private String userId;
private String dimensionId;
private String status;
}
I want the userDimension records from mongoDB based on distinct userId with pagination in spring data mongoDB ?
I am using the query like,
Query query = new Query();
List<UserDimension> userDimensionList = null;
// apply pagination parameters to the search criteria
query.with(pageable);
userDimensionList = mongoTemplate.getCollection("userDimensions").distinct("userId", query.getQueryObject());
But it still giving me the total records.

How to search nested object by using Spring Data Solr?

I have two such Java object:
public class PSubject
{
#Column
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
#org.apache.solr.client.solrj.beans.Field("name")
private String name;
#Column
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
#org.apache.solr.client.solrj.beans.Field("type")
private String type;
#Column
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
#org.apache.solr.client.solrj.beans.Field("uri")
private String uri;
#OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL)
#IndexedEmbedded
#org.apache.solr.client.solrj.beans.Field("attributes")
private Set<PAttribute> attributes = new HashSet<PAttribute>();
.....
}
#Entity
#Indexed
#Table(name="PAttribute")
#Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
public class PAttribute extends PEntity
{
private static final long serialVersionUID = 1L;
#Column
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.YES)
#org.apache.solr.client.solrj.beans.Field("attr_name")
private String name;
#Column
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.YES)
#org.apache.solr.client.solrj.beans.Field("attr_value")
private String value;
.....
}
And my Spring Data Solr query interface:
public interface DerivedSubjectRepository extends SolrCrudRepository<PSubject, String> {
Page<PSubject> findByName(String name, Pageable page);
List<PSubject> findByNameStartingWith(String name);
Page<PSubject> findBy(Pageable page);
#Query("name:*?0* or description:*?0* or type:*?0* or mac_address:*?0* or uri:*?0* or attributes:*?0*")
Page<PSubject> find(String keyword,Pageable page);
#Query("name:*?0* or description:*?0* or type:*?0* or mac_address:*?0* or uri:*?0* or attributes:*?0*")
List<PSubject> find(String keyword);
}
I can search any by name, description, type and mac_address, but can't search any result by attribute.
Update:
For example,when user search "ipod", it's probably means the type of subject or name of subject, or the name of attribute or the value of attribute. And I want get all the matched subject in one request. I know I can search the attribute object in a separate query. But that makes the code in the backend complex.
So, how can I search this nested object?
Update:
I flattened my data:
#Transient
#Field(index=Index.YES, analyze=Analyze.YES, store=Store.NO)
#org.apache.solr.client.solrj.beans.Field("attrs")
private String attrs;
public String getAttrs() {
return attrs;
}
public void setAttrs(Set<PAttribute> attributes) {
StringBuffer attrs = new StringBuffer();
if(attributes==null) {
attributes = this.getAttributes();
}
for(PAttribute attr:attributes){
attrs.append(attr.getName()+" " + attr.getValue()).append(" ");
}
this.attrs =attrs.toString();
}
The issue is resolved.
IIRC it is not possible to store nested data structures in solr - it depends how you flatten your data to fit into an eg. multivalue field - a little hard not knowing your schema.
see: http://lucene.472066.n3.nabble.com/Possible-to-have-Solr-documents-with-deeply-nested-data-structures-i-e-hashes-within-hashes-td4004285.html
How does the data look like in you index, and did you have a look at the http request sent by spring-data-solr?

Resources