I am trying to add a string to the end of an existing array in a mongoDB document.
I have tried looking at the documentation for mongoDB which lead me to the push page and other similar questions. None of them have worked so far as the document that i have have no ids made by me, they are auto-generated as a new element in the array is added.
Document in collection:
_id: 5ce85c1e1c9d4400003dcfd9
name: "Halloween party"
category: 2
date: 2019-10-31T23:00:00.000+00:00
address: "Sample Street, london"
description: "It's Halloween, bring your costumes and your personality to the studen..."
bookings: Array
0: "1610512"
I am able to get the document that I want to append the string in with the following code.
Java Code:
MongoDatabase database = mongoClient.getDatabase("KioskDB");
MongoCollection<Document> Kiosk = database.getCollection("Events");
Document searchQuery = new Document();
searchQuery.put("name", selectedActivityName);
searchQuery.put("bookings", username);
FindIterable<Document> documents = Kiosk.find(searchQuery);
for (Document document: documents){
System.out.println(document);
}
Giving me the following output
Document{{_id=5ce85c1e1c9d4400003dcfd9, name=Halloween party, category=2, date=Thu Oct 31 23:00:00 GMT 2019, address=Sample Street, london, description=It's Halloween, bring your costumes and your personality to the student Bar and join us in this age long celebration., bookings=[1610512]}}
How do I go about appending a new string at the end of the array giving me something like this shown below.
Desired final document
_id: 5ce85c1e1c9d4400003dcfd9
name: "Halloween party"
category: 2
date: 2019-10-31T23:00:00.000+00:00
address: "Sample Street, London"
description: "It's Halloween, bring your costumes and your personality to the studen..."
bookings: Array
0: "1610512"
1: "1859301"
EDIT:
Was able to find the answer with the following code.
DBObject listItem = new BasicDBObject("bookings", username);
Kiosk.updateOne(eq("name", selectedActivityName), new Document().append("$push", listItem));
Where username is the number (Ex: 1859301), selectedActivityName is the name of the name field (Ex: Halloween party) and Kiosk is the collection name.
I will try this code according to the documentation. Ref. https://mongodb.github.io/mongo-java-driver/3.4/driver/getting-started/quick-start/
Document doc = new Document("name", "Halloween party")
.append("bookings", Arrays.asList("1859301"));
Since the 3.0 Java driver they added helper methods for filters which make querying mongo a lot nicer and readable. In 3.1 they also added helper methods for updates which make things like this pretty straightforward and easy to understand what is happening See:
https://mongodb.github.io/mongo-java-driver/3.6/javadoc/com/mongodb/client/model/Filters.html
https://mongodb.github.io/mongo-java-driver/3.6/javadoc/com/mongodb/client/model/Updates.html
Bson query = Filters.eq("name", selectedActivityName);
Bson update = Updates.push("bookings", username);
collection.findOneAndUpdate(query, update);
Doing this in older versions is possible as well. This syntax should still hold true for pre 3.0 versions. However, if you're running older than 3.0 you'll need to replace Document with BasicDBObject.
Bson query = new Document("name", selectedActivityName);
Bson update = new Document("$push", new Document("bookings", username));
collection.findOneAndUpdate(query, update);
Related
Below is my mongob document structure
{
"employee_id":"123",
"employee_name":"ABC",
"elements":[
{
"element_name":"Verification Id",
"element_value":"Test Address",
"element_status":"selected"
},
{
"element_name":"Reportees",
"element_value":["ABC","DEF"],
"element_status":"selected"
}
,
{
"element_name":"Countries",
"element_value":["China","USA"],
"element_status":"selected"
}
]
}
My input will be {"countries":["Russia","Japan"],"Verification Id":"license"}.
My requirement is to update the only the countries and Verification Id element values for the given employee id. Reportees should remain untouched.
What are the ways to achieve this using java mongodb.
I tried following approaches
1)
collection.updateMany(Filters.and(Filters.eq("employee_id", "123"),Filters.eq("elements.element_name", "Verification Id"))
,
Updates.combine(
Updates.set("elements.$.element_value", "license"),
Updates.set("elements.$.element_status", "changed"),
));
and
collection.updateMany(Filters.and(Filters.eq("employee_id", "123"),Filters.eq("elements.element_name", "Countries")))
,
Updates.combine(
Updates.set("elements.$.element_value", ["Russia","Japan"]),
Updates.set("elements.$.element_status", "changed"),
));
The disadvantage here is that I end up making 2 db calls. If more such parameters come as input, then the number of db calls to perform the update increases
2.)
List<DBObject> array = new ArrayList<DBObject>();
BasicDBObject bObj=new BasicDBObject();
bObj.put("element_name", "Countries");
bObj.put("element_value", ["Russia","Japan"]);
bObj.put("element_status", "changed");
BasicDBObject bObj1=new BasicDBObject();
bObj1.put("element_name", "Verification Id");
bObj1.put("element_value", "license");
bObj1.put("element_status", "changed");
array.add(bObj);
array.add(bObj1);
collection.updateMany(Filters.eq("employee_id", "123"),
Updates.combine(
Updates.set("elements", array)
));
The disadvantage is that it completly over writes the elements array and removes the array element "element_name":"Reportees".
PLease guide me further on this. PLease let me know the best way to update select fields based on different criteria.
Suppose a MongoCollection has 2 Documents as shown below
{"employee_id": "1", {"name":"A","age":"18"}}
and
{"employee_id": "2", {"name":"B","age":"18"}}
How can I query this Collection such that it would return me the first Document using only employee_id
Using the following Maven Entries
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
<version>3.5.0-alpha1</version>
</dependency>
The example docs you supplied are not valid JSON; they seem to contain two values "1" and {"name":"A","age":"18"} but only one key: "employee_id".
Assuming ...
The valid document format is:
{"employee_id": "1", "details": {"name":"A","age":"18"}}
You are looking for guidance on using the Mongo Java Driver (this assumption is based on your inclusion of the Maven co-ordinates for that driver).
Then, the following code shows how to find the first document by filtering on employee_id:
#Test
public void canRead() {
MongoClient mongoClient = new MongoClientFactory().create();
MongoCollection<Document> collection = mongoClient.getDatabase("stackoverflow").getCollection("sample");
// this test assumes that the two documents you showed in your question have already been written to the collection e.g.
// collection.insertOne(Document.parse("{\"employee_id\": \"1\", \"details\": {\"name\":\"A\",\"age\":\"18\"}}"));
// collection.insertOne(Document.parse("{\"employee_id\": \"2\", \"details\": {\"name\":\"B\",\"age\":\"18\"}}"));
Bson filter = Filters.eq("employee_id", "1");
Assert.assertEquals(1, collection.count(filter));
Document document = collection.find(filter).first();
Assert.assertEquals("1", document.get("employee_id"));
Document details = (Document) document.get("details");
Assert.assertEquals("A", details.get("name"));
// age is a string?!
Assert.assertEquals("18", details.get("age"));
}
I would like to retrieve the following information:
delete from database where name = 'AAA' and age>20;
but for MongoDB in Java. Essentially, it should delete the document that contain the word AAA and age greater than 20 in them. I know that there is the $in operator in MongoDB, but how do I do the same in Java, using the Java driver? I've been trying to look for it everywhere but am getting nothing. I've tried:
query = new BasicDBObject("age", new BasicDBObject("$gt", "20"), new BasicDBObject("name", "AAA"));
JSON which i want to delete is like this.
{"school" : "NewSchool" , "name" : "AAA" , "age" : "50"}
What you want is the find-term:
{
"name" : "AAA",
"age" : { $gt : 20 }
}
Construct this as your basic DB object, or simply use the new 3.x Filters to create the Bson for you. (As I personally only use 3.x, here's the appropriate example):
MongoClient client = ...
MongoDatabase db = client.getDatabase(...);
MongoCollection<Document> coll = db.getCollection(...);
coll.deleteMany(Filters.and(Filters.eq("name", "AAA"), Filters.gt("age", 20)));
I would like to get the categories of the amazon ,I am planning to scrap not to use API.
I have scrapped the http://www.amazon.com.I have scraped all the categories and sub-categories under Shop By Department drop down .I have created a web service to do this The code is here
#route('/hello')
def hello():
text=list();
link=list();
req = urllib2.Request("http://www.amazon.com",
headers={"Content-Type": "application/json"})
html=urllib2.urlopen(req).read()
soup = BeautifulSoup(html)
last_page = soup.find('div', id="nav_subcats")
for elm in last_page.findAll('a'):
texts = elm.text
links = elm.get('href')
links = links.partition("&node=")[2]
text.append(texts)
link.append(links)
alltext=list();
for i,j in zip(text,link):
alltext.append({"name":i,"id":j})
response.content_type = 'application/json'
print(alltext)
return dumps(alltext)
run(host='localhost', port=8080, debug=True)
I am passing the category name and category id as a JSON object to one of my members to pass it to the API to get the product listing for each category
It is written in JAVA.Here is the code
for (int pageno = 1; pageno <= 10; pageno++) {
String page = String.valueOf(pageno);
String category_string = selectedOption.get("category_name").toString();
String category_id = selectedOption.get("category_id").toString();
final Map<String, String> params = new HashMap<String, String>(3);
params.put(AmazonClient.Op.PARAM_OPERATION, "ItemSearch");
params.put("SearchIndex", category_string);
params.put("BrowseNodeId", category_id);
params.put("Keywords", category_string);
params.put("ItemPage", page);
System.out.println(client.documentToString(client.getXml(params)));
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
Document doc = null;
DocumentBuilder db = dbf.newDocumentBuilder();
InputStream is = client.getInputStream(params);
doc = db.parse(is);
NodeList itemList = doc.getElementsByTagName("Items");
But i am getting this error when i pass the category id as the BrowseNodeId and category name as keyword and search index.
For example
Search Index and Keyword -Amazon Instant Video
BrowseNodeId-2858778011
The value you specified for SearchIndex is invalid. Valid values include [ 'All','Apparel',...................................reless','WirelessAccessories' ].
I would like to know from which amazon url i will get all the categories and its browse nodes
Thank you
I have never looked at Amazon's API before, so this is just a guess but, based on the error message it would seem that "Amazon Instant Video" is not a valid search index. Just because it is there in the drop-down list, doesn't necessarily mean that it is a valid search index.
Here's a list of search indices for US: http://docs.aws.amazon.com/AWSECommerceService/latest/DG/USSearchIndexParamForItemsearch.html . I don't know how up to date it is, but "Amazon Instant Video" does not appear on the list. The error message does include a list of valid search index values, and these do appear to correspond to the above list.
For other locales look here : http://docs.aws.amazon.com/AWSECommerceService/latest/DG/APPNDX_SearchIndexParamForItemsearch.html
I don't think that this is a coding problem per se.
You might like to take a look at python-amazon-product-api. The API might be useful to you, and the documentation might give you some ideas.
I am trying to get the value of a key from a sub-document and I can't seem to figure out how to use the BasicDBObject.get() function since the key is embedded two levels deep. Here is the structure of the document
File {
name: file_1
report: {
name: report_1,
group: RnD
}
}
Basically a file has multiple reports and I need to retrieve the names of all reports in a given file. I am able to do BasicDBObject.get("name") and I can get the value "file_1", but how do I do something like this BasicDBObject.get("report.name")? I tried that but it did not work.
You should first get the "report" object and then access its contents.You can see the sample code in the below.
DBCursor cur = coll.find();
for (DBObject doc : cur) {
String fileName = (String) doc.get("name");
System.out.println(fileName);
DBObject report = (BasicDBObject) doc.get("report");
String reportName = (String) report.get("name");
System.out.println(reportName);
}
I found a second way of doing it, on another post (didnt save the link otherwise I would have included that).
(BasicDBObject)(query.get("report")).getString("name")
where query = (BasicDBObject) cursor.next()
You can also use queries, as in the case of MongoTemplate and so on...
Query query = new Query(Criteria.where("report.name").is("some value"));
You can try this, this worked for me
BasicDBObject query = new BasicDBObject("report.name", "some value");