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
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
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")
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}}}")
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.
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?