Group by multiple fields using mongodb aggregate builders in java application - java

I am fetching data from mongodb and doing some operations using aggregates builders in my java application.
I was able to group by single field using the below piece of code.
Bson group = group("$city", sum("totalPop", "$pop"));
Bson project = project(fields(excludeId(), include("totalPop"), computed("city", "$_id")));
List<Document> results = zips.aggregate(Arrays.asList(group, project)).into(new ArrayList<>());
Now I need to group by using multiple fields...say city and location.
Can someone help on this?

Related

Spring and MongoDB - How to query documents depend on the filters?

I have a project that uploads/download documents, and in the metadata of this documents are in MongoDB. I'm using java spring to store the data into MongoDb. And all is fine to save, get, delete and updates.
The problem is when i try to search the documents depend on a filter.
For example, the filter can be:
Region = Europe, Country = Spain, Category = cat1
or can be just:
Region = Europe, Country = Spain
So the filters are variable, depend on the client selection. They can filter by several fields or just by one or none..
So I don't know how to do that. Because I'm using the repository and if the filter is null, they search by this null value...
For example: If category is null, because the client is not filtering by this field, mongo search the documents by category=null...
Any one can help me?
Thanks,

Extract ObjectId from mongo in java

I'm working on a project and my task is to extract ObjectId from MongoDb i.e. the id of each Document and use that in a JSONObject.
One way to chieve that in Java is by using Aggregation Pipeline.
For example:
List<Bson> aggregation = new ArrayList<>(Arrays.asList(
match(new Document(FIELD, VALUE)), //your match criteria
project(new Document(FIELD1,0).append(FIELD2,0)...))); // hiding fields
// _id field is by default included - so you have to exclude eveything else

Where clause in Phoenix integration with Spark

I am trying to read some data from Phoenix to Spark using its
String connectionString="jdbc:phoenix:auper01-01-20-01-0.prod.vroc.com.au,auper01-02-10-01-0.prod.vroc.com.au,auper01-02-10-02-0.prod.vroc.com.au:2181:/hbase-unsecure";
Map<String, String> options2 = new HashMap<String, String>();
options2.put("driver", "org.apache.phoenix.jdbc.PhoenixDriver");
//options2.put("dbtable", url);
options2.put("table", "VROC_SENSORDATA_3");
options2.put("zkUrl", connectionString);
DataFrame phoenixFrame2 = this.hc.read().format("org.apache.phoenix.spark")
.options(options2)
.load();
System.out.println("The phoenix table is:");
phoenixFrame2.printSchema();
phoenixFrame2.show(20, false);
But I need to do a select with where clause, I also used the dbtable which is used for a JDBC connection in Spark but I guess it doesn't have any effect!
Based on the documentation
"In contrast, the phoenix-spark integration is able to leverage the underlying splits provided by Phoenix in order to retrieve and save data across multiple workers. All that’s required is a database URL and a table name. Optional SELECT columns can be given, as well as pushdown predicates for efficient filtering."
But seems there is no way to parallelize the reading from Phoenix, it would be really inefficient to read the whole table in a Spark Dataframe and then doing filtering, but it seems I can find a way to apply a where clause. Does anyone know how to apply where clause in my above codes?

How to apply the search in list type field in dynamodb?

We are using $all in mongodb repository like below:
#Query(value = "{ 'subscriptions' : {$all : ?0 }}")
public List<ContentItem> findBySubscription(String[] subscriptionCode);
it works good for mongo but we need its alternative in dynamodb
The below solution uses AWS SDK DynamoDB. Currently, I think there is only community version of Spring data available for DynamoDB. So, I have provided the solution using AWS SDK.
QuerySpec Class
The CONTAINS comparison operator can be used to search for the values in LIST data type.
CONTAINS is supported for lists: When evaluating "a CONTAINS b", "a"
can be a list; however, "b" cannot be a set, a map, or a list.
Example:-
QuerySpec querySpec = new QuerySpec();
querySpec.withKeyConditionExpression("yearkey = :yearval and title = :title")
.withFilterExpression("contains (subscriptions, :subscriptions)")
.withValueMap(
new ValueMap().withNumber(":yearval", yearKey)
.withString(":title", title)
.withString(":subscriptions", subscriptions));
Edit:-
Currently, the second parameter can't be list because the API can't process it as per the specification. The workaround would be to use AND condition with multiple CONTAINS. Example below:-
.withFilterExpression("contains (subscriptions, :subscriptions1) AND contains (subscriptions, :subscriptions2)")

Transform Cassandra query result to POJO with Astyanax

I am working in a Spring web application using Cassandra with Astyanax client. I want to transform result data retrieved from Cassandra queries to a POJO, but I do not know which library or Astyanax API support this.
For example, I have User column family (CF) with some basic properties (username, password, email) and other related additional information can be added to this CF. Then I fetch one User row from that CF by using OperationResult> to hold the data returned, like this:
OperationResult<ColumnList<String>> columns = getKeyspace().prepareQuery(getColumnFamily()).getRow(rowKey).execute();
What I want to do next is populating "columns" to my User object. Here, I have 2 problems and could you please help me solve this:
1/ What is the best structure of User class to hold the corresponding data retrieved from User CF? My suggestion is:
public class User {
String userName, password, email; // Basic properties
Map<String, Object> additionalInfo;
}
2/ How can I transform the Cassandra data to this POJO by using a generic method (so that it can be applied to every single CF which has mapped POJO)?
I am so sorry if there are some stupid dummy things in my questions, because I have just approached NoSQL concepts and Cassandra as well as Astyanax for 2 weeks.
Thank you so much for your help.
You can try Achilles : https://github.com/doanduyhai/achilles, an JPA compliant Entity Manager for Cassandra
Right now there is a complete implementation using Thrift API via Hector.
The CQL3 implementation using Datastax Java Driver is in progress. A beta version will be available in few months (July-August 2013)
CQL3 is great but it's still too low level because you need to extract the data yourself from the ResultSet. It's like coming back to the time when only JDBC Template was available.
Achilles is there to fill the gap.
I would suggest you to use some library like Playorm using which you can easily perform CRUD operations on your entities. See this for an example that how you can create a User object and then you can get the POJO easily by
User user1 = mgr.find(User.class, email);
Assuming that email is your NoSqlId(Primary key or row key in Cassandra).
I use com.netflix.astyanax.mapping.Mapping and com.netflix.astyanax.mapping.MappingCache for exactly this purpose.

Categories