How to get a specific value in Mongodb using Java? - java

In command prompt I enter the following:
db.products.insert( { item: "card", qty: 15 } )
I wanted to know how would I be able to get the item value from java.
I want to create a variable called item and it would know the value of it which is "card".
I am currently using MongoOperations in java but I do not know how to get only one value from MongoDB.
Pojo
#Document(collection="products")
public class ValueServerModel{
#Id
private String id;
String item;
int qty;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public int getQty() {
return qty;
}
public void setQty(int qty) {
this.qty = qty;
}
public Product(String item, int qty) {
//super();
this.item = item;
this.qty = qty;
}
#Override
public String toString() {
return "Product [id=" + id + ", item=" + item + ", qty=" + Integer.toString(qty) + "]";
}
}
//provided by suwal
Long Shot Attempt
#Autowired
MongoOperations mongoOperations;
#PostConstruct
public List<SomeModel> getList() {
List<SomeModel> pmLst = mongoOperations.findAll(ServerModel.class);
//code above works I get a list of values based on mongo db
//attempting to retrieve one value, (stuck)
String value = mongoOperations.find("test", ValueServerModel.class);
With command prompt
I am able to get a value by using the following command:
db.products.find({}, {qty:0, _id:0})
//output ("item": "card")
I want to achieve the following:
db.products.find({}, {item})
//output should be "card".
is it possible to do what I just did above?

You can use projection to request the fields.
Something like
Query query = new Query();
query.fields().include("item").exclude("_id");
Product product = mongoOperations.findOne(query, Product.class);
This will populate the product pojo with item field.
You can use native mongo java driver to request the fields directly.
Something like
MongoClient mongoClient = new MongoClient( "localhost" , 27017 );
MongoDatabase database = mongoClient.getDatabase(db_name);
MongoCollection<Document> collection = database.getCollection(collection_name);
String value = collection.find().projection(Projections.include("item")).first().getString("item");

I get that you want to get the value, but you are not specifying based on what. That is "what is your query condition". Also not sure what ServerModel and ValueServerModel classes are, but let see if this general idea helps you.
Lets say you have following structure stored after your insert query in the collection products
{
"_id" : ObjectId("5939d5a1d0ffa3f0209fd42f"),
"item" : "card",
"qty" : 15
}
You will need a model representing the collection,
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection="products") //this is what binds this class to your collection
public class Product {
#Id
private String id;
String item;
int qty;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public int getQty() {
return qty;
}
public void setQty(int qty) {
this.qty = qty;
}
public Product(String item, int qty) {
//super();
this.item = item;
this.qty = qty;
}
#Override
public String toString() {
return "Product [id=" + id + ", item=" + item + ", qty=" + Integer.toString(qty) + "]";
}
}
Now in your code you would have something like this,
// findOne returns you single instance of an object of the specified type
Product product = mongoOperation.findOne(
new Query(Criteria.where("item").is("card")), Product.class);
System.out.println(product); //Output => Product [id=5939d5a1d0ffa3f0209fd42f, item=card, qty=15]
String value = product.getItem();
System.out.println("value is " + value);//Output => card
Lets say you want to get by id instead, so you would have something like this
Product product2 = mongoOperation.findOne(
new Query(Criteria.where("_id").is("5939d5a1d0ffa3f0209fd42f")),
Product.class);
System.out.println(product2);

Related

Ignore existing item in the LInkedList

I am trying to ignore the existing item that I added in the duplicate.
Normally, if the item does not exist it will eventually added the item to the
LinkedList
When I try to added item again, I just wanted to ignore the adding process and the increment the value by 1.
But the problem is it keep adding the items to the LinkedList.
Can someone explain to me?
class Item{
Store store;
String name;
String code;
String number;
public Item(String name, String code){
this.name = name;
this.code = code;
number = 0;
}
public boolean itemExists(String name, String code){
return this.name.equals(name) && this.code.equals(code);
}
public void increment(){ number++; }
#Override
public String toString(){ return store.getName()+ " " + name + " " + code + " " +number; }
}
Items will be added to the factory.
class Factory{
private LinkedList<Item> items = new LinkedList<Item>():
private String name;
private String number;
public Factory(String name, String number){
this.name = name;
this.number = number;
}
public void getName(){
return name;
}
public void addItem(String name, String code){
items.add(new Item(this, name, code));
}
#Override
public String toString(){ return name + " " + number; }
public List<Item> getItems{
return items;
}
}
The factory then delivery to the store.
class Store{
private LinkedList<Factory> factories = new LinkedList<>();
public Store(){
factories.add(new Factory("MayFlower", "01");
factories.add(new Factory("SunFlower", "02");
factories.get(0).addItem("GTA", "001A");
factories.get(0).addItem("GTA", "002A");
factories.get(0).addItem("GTA", "003A");
factories.get(1).addItem("Sonic", "022A");
factories.get(1).addItem("Sonic", "023B");
factories.get(1).addItem("Sonic", "024C");
}
public List<Item> getItemFromFact(){
List<Item> temp = new ArrayList<>();
for(Factory factory: factories)
for(Item item: factory.getItems())
temp.add(item);
return temp;
}
}
The customer buy items at the store.
class Customer{
private LinkedList<Item> items = new LinkedList<>();
public static void main(String args[]){
new Customer.view();
}
private void view(){
for(Item item: items)
System.out.println(item);
}
private void adding(){
String name = "GTA";
String code = "001A":
List<Item> item = item(name, code);
if(!item.isEmpty()){
items.add(item);
item.increment(); // will increment the value;
}
else{
System.out.println("Item does not exists");
}
}
private List<Item> item(String name, String code){
List<item> temp = new ArrayList<>();
List<item> fromStore = new Store().getItemFromFact();
for(Item item: fromStore)
if(item.itemExists(name, code))
temp.add(item)
return temp;
}
}
The main problem is in the item class under item(). If I try with the same item again, it will just add another it become like this.
MayFlower GTA 001A 1
MayFlower GTA 001A 1
The result should be
MayFlower GTA 001A 2
after I added another item.
I problem I have is that I don't know how to match the item from exisiting.
If someone know the solution.
That's would be very helpful thanks.
There are so many problems in your design and code. I've discussed some of them as given below:
I do not understand why you need a reference to Store in Item. An Item should not know which Store or Factory it is going to belong to.
I also didn't understand the purpose of the attribute, number in Store. An Item shouldn't know how many numbers of it is present in a Store or Factory. If you keep it for any reason, it should be of a numeric type (e.g. int, double etc.) so that you can perform arithmetic operations on it.
Instead of a LinkedList of Item objects in Factory, you should have a variable of type, Map<String, Integer> and you can call it stock. The key in this Map is the unique identifier of the item, which is the combination code and name as per your requirement and the value will be the available number/quantity of the Item. Given below is a minimal verifiable example of how you can maintain stock:
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
class Item {
String name;
String code;
public Item(String name, String code) {
this.name = name;
this.code = code;
}
public String getName() {
return name;
}
public String getCode() {
return code;
}
#Override
public String toString() {
return "Name: " + name + "Code :" + code;
}
}
class Factory {
private Map<String, Integer> stock = new HashMap<String, Integer>();
private String name;
public Factory(String name) {
this.name = name;
}
public void addItem(Item item) {
if (item != null) {
String key = item.getName() + ":" + item.getCode();
stock.put(key, stock.getOrDefault(key, 0) + 1);
}
}
public void showStock() {
for (Entry<String, Integer> entry : stock.entrySet()) {
System.out.println("Item = " + entry.getKey() + ", Available quantity = " + entry.getValue());
}
}
}
public class Main {
public static void main(String[] args) {
Factory factory = new Factory("MayFlower");
factory.addItem(new Item("GTA", "001A"));
factory.addItem(new Item("GTA", "001A"));
factory.addItem(new Item("GTA", "002A"));
factory.addItem(new Item("GTA", "003A"));
factory.addItem(new Item("GTA", "003A"));
factory.addItem(new Item("GTA", "003A"));
factory.showStock();
}
}
Output:
Item = GTA:002A, Available quantity = 1
Item = GTA:003A, Available quantity = 3
Item = GTA:001A, Available quantity = 2

How do I sort elements of 2 lists by their id which have been merged?

I have merged the above list but need to sort it based on the id param. How do I do that in the easiest and the optimal way possible?
I have a set of 2 users which I initially merged and now I would like to sort them based on their id and then display the results. Any ideas?
import java.io.*;
import java.util.*;
/*
* To execute Java, please define "static void main" on a class
* named Solution.
*
* If you need more classes, simply define them inline.
*/
class Employee {
public String name;
public int id;
Employee(String name, int id) {
this.name = name;
this.id = id;
}
public String toString() {
return "<name: " + this.name + ", id: " + this.id + ">";
}
}
class Person {
public String name;
public int id;
Person(String name, int id) {
this.name = name;
this.id = id;
}
public String toString() {
return "<name: " + this.name + ", id: " + this.id + ">";
}
}
public class Solution {
public static void main(String[] args) {
List<Employee> employee = generateEmployees();
List<Person> persons = generatePersons();
ArrayList<Object> merged = new ArrayList<Object>(employee);
merged.addAll(person);
System.out.println("merged:"+merged +"\n");
for(int i=0;i<users.size();i++){
if(person.get(i).id<=5){
System.out.println("UserName:"+person.get(i).name+"\n");
}
}
for(int i=0;i<employee.size();i++){
if(employee.get(i).id<=5){
System.out.println("DesignerName:"+employee.get(i).name+"\n");
}
}
});
}
Thanks in advance!
I have looked at several methods online for sorting but couldnt figureo ut which was the best way to use it.Just want to display results once its sorted
User and Designer must extend from one same class. (or Designer extand user).
Then you create a Comparator (javadoc) and you use merged.sort (myComparator) (javadoc)
[EDIT]
class MyComparator implements Comparator<User> {
#Override
public int compare(User o1, User o2) {
return Integer.compare(o1.id, o2.id);
}
}
public class User {
public String name;
public int id;
User(String name, int id) {
this.name = name;
this.id = id;
}
public String toString() {
return "<name: " + this.name + ", id: " + this.id + ">";
}
}
public class Designer extends User{
Designer(String enter code herename, int id) {
super(name, id);
}
}
public class Solution {
public static void main(String[] args) {
...
ArrayList<User> merged = new ArrayList<User>(designers);
merged.addAll(users);
merged.sort(new MyComparator());
...
}
}
Assuming that you have list of User that is called users:
users.stream().sorted(Comparator.comparing(User::getId)).forEach(System.out::println);

Constructor cannot be applied

i was doing this tutorial on Android Studio Development Essentials 6th Edition, the tutorial was about SQLiteDatase so i wrote evrything but i kept on getting an error whenever i try calling the Product Constructor everything is correct on the book but i cant get it right, this is the find Product Constructor and my Product class.
Find product
public Product findProduct(String productname) {
String query = "Select * FROM " + TABLE_PRODUCTS + " WHERE " +
COLUMN_PRODUCTNAME + " = " + productname + ";";
SQLiteDatabase db = this.getWritableDatabase();
Cursor cursor = db.rawQuery(query, null);
Product product = new Product();// Cannot be applied
if (cursor.moveToFirst()) {
cursor.moveToFirst();
product.setId(Integer.parseInt(cursor.getString(0)));
product.setProductName(cursor.getString(1));
product.setQuantity(Integer.parseInt(cursor.getString(2)));
cursor.close();
} else {
product = null;
}
db.close();
return product;
}
My Product Class
public class Product {
private int id;
private String ProductName;
private int Quantity;
public Product(int _id, String _productname, int _quantity) {
this.id = _id;
this.ProductName = _productname;
this.Quantity = _quantity;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getProductName() {
return ProductName;
}
public void setProductName(String productName) {
this.ProductName = productName;
}
public int getQuantity() {
return Quantity;
}
public void setQuantity(int quantity) {
this.Quantity = quantity;
}
}
Thank you.
public Product(int _id, String _productname, int _quantity) {
is the only constructor in you Product class definition (you don't have any others), so you have to call its constructor with these 3 parameters - instead of
Product product = new Product();// Cannot be applied
use something as
Product product = new Product(132, "Wheel", 1000);
Another solution:
Add another constructor in your Product class besides existing one, e. g. an empty one:
public Product() {}
(it may be located before or after your existing one).
If You created Your own constructor, the default one is not generated. Please take a look at Java default constructor
Regards

Can't insert more than 1 entity (batch insert) with Azure - JAVA

I am trying to insert a batch of Entities with Azure.
For my "CustomerEntity", all works as expected, but for my "OrderEntity", I can only have a single entity in my batch operation...
Here is my code:
public void batchInsertTransaction(ArrayList<Transaction> transactions){
try
{
// Retrieve storage account from connection-string.
CloudStorageAccount storageAccount =
CloudStorageAccount.parse(storageConnectionString);
// Create the table client.
CloudTableClient tableClient = storageAccount.createCloudTableClient();
// Define a batch operation.
TableBatchOperation batchCustomerOperation = new TableBatchOperation();
TableBatchOperation batchOrderOperation = new TableBatchOperation();
// Create a cloud table object for the table.
CloudTable cloudCustomerTable = tableClient.getTableReference("Customer");
CloudTable cloudOrderTable = tableClient.getTableReference("Order");
String partitionKey = "transaction-" + PropertiesManager.country + "-" + PropertiesManager.city;
for(int i = 0; i < transactions.size(); i++){
Transaction transaction = transactions.get(i);
Order order = transaction.getOrder();
Customer customer = transaction.getCustomer();
// Create a customer entity to add to the table.
CustomerEntity customerEntity = new CustomerEntity(partitionKey, customer.getGlobalId());
customerEntity.setCountry(customer.getCountry());
customerEntity.setName(customer.getName());
customerEntity.setGlobalId(customer.getGlobalId());
batchCustomerOperation.insertOrReplace(customerEntity);
OrderEntity orderEntity = new OrderEntity(partitionKey, order.getGlobalId());
orderEntity.setComplete(order.getComplete());
orderEntity.setCustomerId(order.getCustomerId());
orderEntity.setGlobalId(order.getGlobalId());
orderEntity.setOrderDate(order.getOrderDate());
orderEntity.setPrice(order.getPrice());
orderEntity.setSku(order.getSku());
orderEntity.setId(order.getId());
batchOrderOperation.insertOrReplace(orderEntity);
}
// Execute the batch of operations on the "people" table.
cloudCustomerTable.execute(batchCustomerOperation);
cloudOrderTable.execute(batchOrderOperation);
}
catch (Exception e)
{
// Output the stack trace.
e.printStackTrace();
}
}
Here is my "OrderEntity"
package entities;
import com.microsoft.azure.storage.table.TableServiceEntity;
public class OrderEntity extends TableServiceEntity {
int orderId;
int customerId;
String globaOrderlId;
String sku;
String orderDate;
double price;
int complete;
public OrderEntity(){ }
public OrderEntity(String partitionKey, String globalId){
this.partitionKey = partitionKey;
this.rowKey = globalId;
}
public void setComplete(int complete){
this.complete = complete;
}
public void setCustomerId(int id){
this.customerId = id;
}
public void setGlobalId(String id){
this.globaOrderlId = id;
}
public void setPrice(double price){
this.price = price;
}
public void setOrderDate(String date){
this.orderDate = date;
}
public void setSku(String sku){
this.sku = sku;
}
public void setId(int id){
this.orderId = id;
}
public String getGlobalId(){
return this.globaOrderlId;
}
public int getId(){
return this.orderId;
}
public int getCustomerId(){
return this.customerId;
}
public String getSku(){
return this.sku;
}
public String getOrderDate(){
return this.orderDate;
}
public double getPrice(){
return this.price;
}
public int getComplete(){
return this.complete;
}
}
I have tried commenting out the customer code, as well as all of the order entity set properties, but still... I can only have a single entity in my "batchOrderOperation".
If I have any more, I get an error:
com.microsoft.azure.storage.table.TableServiceException: Bad Request at
com.microsoft.azure.storage.table.TableBatchOperation$1.postProcessResponse(TableBatchOperation.java:548)
at com.microsoft.azure.storage.table.TableBatchOperation$1.postProcessResponse(TableBatchOperation.java:434)
at com.microsoft.azure.storage.core.ExecutionEngine.executeWithRetry(ExecutionEngine.java:148)
at com.microsoft.azure.storage.table.TableBatchOperation.execute(TableBatchOperation.java:419)
at com.microsoft.azure.storage.table.CloudTable.execute(CloudTable.java:495)
at com.microsoft.azure.storage.table.CloudTable.execute(CloudTable.java:452)
at managers.TableManager.batchInsertTransaction(TableManager.java:120)
at managers.QueueManager.process(QueueManager.java:40)
at App.main(App.java:32)
Does anyone know what the problem is?
Funny how I spend hours looking for the solution and as soon as I resort to asking for help, I find the answer...
It turns out that my rowKeys were identical, and rowKeys must be unique for any given partition:
http://msdn.microsoft.com/en-us/library/dd179338.aspx
The row key is a unique identifier for an entity within a given
partition
Hope this helps someone else one day.

How to compare Objects attributes in an ArrayList?

I am fairly new to Java and I have exhausted all of my current resources to find an answer. I am wondering if it possible to access an Objects first property to see if it matches a particular integer?
For example, I am trying to obtain a Product that is within my Database by searching for it by it's Product ID. Therefore, if I create two products such as, Product ipad = new Product(12345, "iPad", 125.0, DeptCode.COMPUTER); and Product ipod = new Product(12356, "iPod", 125.0, DeptCode.ELECTRONICS); (I have included this Product class below), and add them to an Arraylist such as, List<Product> products = new ArrayList<Product>(); how can I loop through this ArrayList in order to find that product by its ID?
This is the method I am working on:
List<Product> products = new ArrayList<Product>();
#Override
public Product getProduct(int productId) {
// TODO Auto-generated method stub
for(int i=0; i<products.size(); i++){
//if statement would go here
//I was trying: if (Product.getId() == productId) {
System.out.println(products.get(i));
}
return null;
}`
I know that I can include a conditional statement in the for loop but I cant figure out how to access the getId() method in the Product class to compare it the productId parameter?
package productdb;
public class Product {
private Integer id;
private String name;
private double price;
private DeptCode dept;
public Product(String name, double price, DeptCode code) {
this(null, name, price, code);
}
public Product(Integer id, String name, double price, DeptCode code) {
this.id = id;
this.name = name;
this.price = price;
this.dept = code;
}
public String getName() {
return name;
}
public double getPrice() {
return price;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public DeptCode getDept() {
return dept;
}
public void setDept(DeptCode dept) {
this.dept = dept;
}
public void setName(String name) {
this.name = name;
}
public void setPrice(double price) {
this.price = price;
}
#Override
public String toString() {
String info = String.format("Product [productId:%d, name: %s, dept: %s, price: %.2f",
id, name, dept, price);
return info;
}
}
Please let me know
You have already got the Product out of the List<Product> in the following statement:
System.out.println(products.get(i));
Now, that you have got Product, now to get it's id, you can just call it's getId() method:
if (product.get(i).getId() == productId) {
// Return this product.
}
I would also suggest you to use enhanced for-loop instead of the traditional loop like this:
for (Product product: products) {
// Now you have the product. Just get the Id
if (product.getId() == productId) {
return product;
}
}
Also, you should change the type of productId from Integer to int. You don't need a wrapper type there.
Have you considered using a HashMap (or LinkedHashMap) instead of an Array. This way you can use the productId as the key and the product as the value?
This will let you get the object without having to loop through the entire array.
For comparing the ArrayList Objects make override equal function in your CustomObject Class Like Employee.
ArrayList<Employee> list;
Employee emp;
//suppose you have some number of items in that list and emp object contains some value.
int size=list.size();
for(int i=0;i<size;i++) {
if(list.get(i).equals(emp)) {
//todo perform operation on the basis of result.
}
}
And suppose this is your Employee class and in that class you need to override the equal function.
class Employee{
int age;
String name;
public int getAge() {
return this.age;
}
public String getName() {
return this.name;
}
public void setAge(int emp_age) {
this.age=emp_age;
}
public void setName(String emp_name) {
this.name=emp_name;
}
#Override
public boolean equal(Employee emp) {
boolean isEqual=false;
if(emp!=null && emp instanceof Employee) {
isEqual=(this.age==emp.age);
}
return isEqual;
}
}
I hope this solution will help you to check for equal values and compare the values.
Thanks
According to your commented line //I was trying: if (Product.getId() == productId) I think where you were falling over is using Product (capital P). What you needed was:
if (products.get(i).getId() == productId)
Also, you weren't returning the product you found...
The problem with that form is that a) you have to find the product in the list twice (once in the condition and then again when printing the result - a third time if you returned the product) and b) it will throw a null pointer exception if the product you are looking for is not in the list.
This is a nicer, more compact way of doing it:
#Override
public Product getProduct(int productId)
{
for(Product product : products)
{
if (productId == product.getId())
{
System.out.println(product.toString());
return product;
}
}
return null;
}

Categories