how to perform solr joins - java

Hi i am trying to join two documents from two collections in solr
Solr document-1 Collection-A
{
"student_id": "123",
"name": "rahul",
"adrress": "addr001"
}
solr document-2 Collection-B
{
"address_id": "addr001",
"street_name": "XYZ street",
"colony": "ABC colony"
}
I am expecting my final document should be like below after join
{
"student_id": "123",
"name": "rahul",
"street_name": "XYZ street",
"colony": "ABC colony"
}
Can anyone help me how to perform joins in solr with relevant example as per my requirements ?

Related

Elasticsearch query Combine 2 queries or Elastic search Join Query

This is my one elastic document example:
"_source": {
"leg_b":{
"team_name" : "aaaa",
"channel_uuid" : "12121"
},
wrapup":[
"0":{
"name": "sss",
"channel_uuid": "12121"
},
"1":{
"name": "bbb",
"channel_uuid" : "21212"
},
"2":{
"name": "acbs",
"channel_uuid" : "111211"
}
]
}
I have to perform search on "leg_b.team_name" value and find out its "channel_uuid" value on the basis of leg_b's "channel_uuid",NEXT I will search in wrapup object for common "channel_uuid" values in the Same Query.
Example,
lets consider above document, First I will search on leg_b.team_name = "aaaa" after that I will take leg_b.channel_uuid = "12121" and search on wrapup object channel_uuid.
Explaination:
So there are two searches are going on 1) leg_b.team_name="aaaa" which returns this document and after that 2) on the returned doc which I got from 1st search, I will take its leg_b.channel_uuid to search on wrapup common channel uuid. (i.e, leg_b channel_uuid is "12121" so I should get "wrapup" channel_uuid : "12121" objects. It exclude "acbc" because its channel_uuid : "111211".
So it should return,
"_source": {
"leg_b":{
"team_name" : "aaaa",
"channel_uuid" : "12121"
},
"wrapup":[
"0":{
"name": "sss",
"channel_uuid": "12121"
},
"1":{
"name": "bbb",
"channel_uuid" : "21212"
}
]
}
Please suggest some approach, Thank you.

How to design data for complex recursive entities for persistence?

I was assuming that I have an entity as "Person".
{
"UnqIdr": 125,
"FrstNm": "Mark",
"LastNm": "Antony",
"Gndr": "Male",
"DtOfBirth": "06-09-2020",
"CtctDtls": {
"Addr": [
{
"UnqIdr": "10001",
"Ln1": "Street name",
"Ln2": "Block Number",
"Ln3": "Ward number",
"Cty": "New York",
"ZipCd": "60034",
"Stat": "New Jersey",
"Ctry": "North America",
"IsPrmy": true
}
],
"PhneNb": [
{
"Nm": "Principal",
"CtryCd": "+1",
"Nb": "1234567890",
"IsPrmy": true
}
],
"Email": "abc#def.com",
"CtctURL": "www.def.com",
"SclMdia": {
"FacebookURL": "www.facebook.com/def",
"LinkedInURL": "www.linkedin.com/us/def",
"TwitterURL": "www.twitter.com/3634556"
}
},
"IdntyProof": [{
"UnqIdr": 16537,
"Ctry": "India",
"IdntyTp": 6548,
"IdntyIdr": "INYHGB3462",
"IsVerified": true,
"VldFrm": "16-01-2000",
"VldTill": "4-12-2023"
}],
"PrsnlIdnty": {
"BldGrp": "A",
"Id":[{
"Nt": "Mole in right arm"
}]
},
"Ethncty": "Nadar",
"Rlgn": "Hindu",
"Ntnlty": "Indian",
"PrvsNtnlty": [{
"Ntnlty": "Indian",
"IdntyProof": [{
"UnqIdr": 16537,
"Ctry": "India",
"IdntyTp": 6548,
"IdntyIdr": "INYHGB3462",
"IsVerified": true,
"VldFrm": "16-01-2000",
"VldTill": "4-12-2023"
}]
}],
"MrtlSts": "Married",
"Rltsh": [{
"RltshTp": "Spouse",
"UnqIdr": 134
},{
"RltshTp": "Divorcee",
"UnqIdr": 130
}]
}
However, the same information applies to an Employee, Customer and few more.
Structure of employee might be
{
"UnqIdr": 125,
"Department": "Chem Lab",
"Person": {...}
}
However, when building the logic, we found an employee can also be a customer. Hence we thought of bundling as follows:
{
//person-info
"employee-info": {},
"customer-info": {}
}
Now the problem comes up[ how to query with employee-info or customer-info.
I know it is data design; however, we are using Java 11 and Spring JPA for the same.
Additionally, which would be effective ways to design the solution. Even using NoSQL database is open for discussion.
Look for data normalization with relational databases.
A simple solution is to store Person object in a different table and assigning it a personId field.
So the employee structure becomes:
{
"UnqIdr": 125,
"Department": "Chem Lab",
"PersonId": 420
}
Relational databases are made for such data domains (eventual consistency for people....... no please).
Look here for some database design involving CUSTOMER and EMPLOYEE:
https://www.oracletutorial.com/getting-started/oracle-sample-database/
Now, you can still have Java inheritance regarding these People common attributes.

How to query MongoDb subdocuments in Java

Dear MongoDb Experts out there! I am new to Mongo and I am currently working with a MongoDb with Java.
Having a MongoDb with a collection called "teams" with the following example structure:
{[
{
"id": "123",
"name": "Dev1",
"employees": [
{"name": "John", "age": 30},
{"name": "Jane", "age": 30}
]
},
{
"id": "456",
"name": "Dev2",
"employees": [
{"name": "Mike", "age": 30},
{"name": "Oscar", "age": 27}
]
}
]}
I want to have a query which returns an array with all employees, that are 30 years old. So the expected result would be:
{[
{"name": "John", "age": 30},
{"name": "Jane", "age": 30},
{"name": "Mike", "age": 30}
]}
It would be even better to only get the employees name (since I know the age I searched for), like:
{[
{"name": "John"},
{"name": "Jane"},
{"name": "Mike"}
]}
I have a MongoCollection object:
MongoCollection<Document> collection = mongoClient
.getDatabase(databaseName)
.getCollection("teams")
My question: Is it possible to retrieve my expected result from the MongoDb? If so, which operations do I have to call on my collection object?
Approach 1: Find with $elemMatch projection
db.getCollection('teams').find(
{"employees.age":30},
{ "employees": { "$elemMatch": { "age": 30 } },"_id":0 }
)
Output Format:
{
"employees" : [
{
"name" : "John",
"age" : 30.0
}
]
}
{
"employees" : [
{
"name" : "Mike",
"age" : 30.0
}
]
}
Approach 2: Aggregate with $unwind and key renaming using $projection
db.getCollection('teams').aggregate([
{"$match": {"employees.age":30}} ,
{"$unwind": "$employees"},
{"$match": {"employees.age":30}} ,
{"$project": {"name": "$employees.name","_id":0}}
])
Output format:
{
"name" : "John"
}
{
"name" : "Jane"
}
{
"name" : "Mike"
}
Approach 1 would be faster, but require additional work at app layer. It is recommended to offload formatting tasks to app servers rather than on db itself.
Approach 2 can instantly give to the formatted results, doing the querying and formatting both in the database servers

MongoDB Java Driver aggregation with regex filter

I am using MongoDB Java Driver 3.6.3.
I want to create regex query with group by aggregation to retrieve distinct values.
Let's say I have json:
[{
"name": "John Snow",
"category": 1
},
{
"name": "Jason Statham",
"category": 2
},
{
"name": "John Lennon",
"category": 2
},
{
"name": "John Snow",
"category": 3
}]
I want to create query where regex is like "John.*" and group it by name so there would be only one "John Snow"
Expected result is:
[{
"name": "John Snow",
"category": 1
},
{
"name": "John Lennon",
"category": 2
}]
The answer provided by felix is correct, in terms of Mongo Shell commands. The equivalent expression of that command using the MongoDB Java driver is:
MongoClient mongoClient = ...;
MongoCollection<Document> collection = mongoClient.getDatabase("...").getCollection("...");
AggregateIterable<Document> documents = collection.aggregate(Arrays.asList(
// Java equivalent of the $match stage
Aggregates.match(Filters.regex("name", "John")),
// Java equivalent of the $group stage
Aggregates.group("$name", Accumulators.first("category", "$category"))
));
for (Document document : documents) {
System.out.println(document.toJson());
}
The above code will print out:
{ "_id" : "John Lennon", "category" : 2 }
{ "_id" : "John Snow", "category" : 1 }
You can achieve this with a $regex in $match stage, followed by a $group stage:
db.collection.aggregate([{
"$match": {
"name": {
"$regex": "john",
"$options": "i"
}
}
}, {
"$group": {
"_id": "$name",
"category": {
"$first": "$category"
}
}
}])
output:
[
{
"_id": "John Lennon",
"category": 2
},
{
"_id": "John Snow",
"category": 1
}
]
you can try it here: mongoplayground.net/p/evw6DP_574r
You can use Spring Data Mongo
like this
Aggregation agg = Aggregation.newAggregation(
ggregation.match(ctr.orOperator(Criteria.where("name").regex("john", "i")),
Aggregation.group("name", "category")
);
AggregationResults<CatalogNoArray> aggResults = mongoTemp.aggregate(agg, "demo",demo.class);

CosmoDB querying a value within an array using Mongo driver does not seem possible

We are migrating from mongoDB to CosmoDB using the Mongo Java Client. We have encountered the following difference in query behavior with arrays.
We have documents that look something like the following
[{
"name":"garry",
"pets":["cats","dogs"]
},
{
"name":"sally",
"pets":["cats","fish"]
}]
using mongo a query for
find({"pets":"cats"})
will return garry and sally however using cosmoDB we get zero results.
Is there a way to modify the query to replicate the same mongo behavior?
We also have documents that look something like the following that we query on type
[{
"name": "garry",
"pets": [{
"type": "cat",
"name": "Mittens"
}, {
"type": "dog",
"name": "Max"
}]
},
{
"name": "sally",
"pets": [{
"type": "cat",
"name": "Paul"
}, {
"type": "fish",
"name": "Bubbles"
}]
}
]
current mongo queries look like
find({"pets.type": "fish"})
in
I tried to use the query below, it works.
Using MongoShell.
find({"pets": {$all: ["cats"]}})
For Mongo Java Driver
FindIterable<Document> queryResult = collection.find(Filters.all("pets", "cats"));

Categories