How to use spring mongo query criteria based only for below thing.
I don't want to use spring mongo save method even though its doing upsert because of application is running in multi threaded environment so only specified values should updated and remaining values will not change.
Suppose the document looks like:
{
"dept": "FY",
"companyName": "TIS",
"id":"112234",
"contacts": [{
"name": "Jeff",
"phone": "222 - 572 - 8754"
},
{
"name": "Joe",
"phone": "456 - 875 - 4521"
},
{
"name": "Alex",
"phone": "789 - 875 - 4521"
}
]
}
based on id and the array list passing to update method the contacts list should update.
Lets take based on id=112234 and passing contacts list to update method, based on contact name it should update.
"contacts": [{
"name": "Jeff",
"phone": "111 - 000 - 123"
},
{
"name": "Joe",
"phone": "980 - 546 - 0000"
}
]
the final mongo json document should updated as below:
{
"dept": "FY",
"companyName": "TIS",
"id":"112234",
"contacts": [{
"name": "Jeff",
"phone": "111 - 000 - 123"
},
{
"name": "Joe",
"phone": "980 - 546 - 0000"
},
{
"name": "Alex",
"phone": "789 - 875 - 4521"
}
]
}
Related
I am new to mongoDB modelling, I have been working in a small app that just used to have one collection with all my data like this:
{
"name": "Thanos",
"age": 999,
"lastName": "whatever",
"subjects": [
{
"name": "algebra",
"mark": 999
},
{
"name": "quemistry",
"mark": 999
},
{
"name": "whatever",
"mark": 999
}
]
}
I know this is standard in mongoDB since we don't have to map relotionships to other collections like in a relational database. My problem is that my app is growing and my json, even tho it works perfectly fine, it is starting to be huge since it has a few more (and quite big) nested fields:
{
"name": "Thanos",
"age": 999,
"lastName": "whatever",
"subjects": [
{
"name": "algebra",
"mark": 999
},
{
"name": "quemistry",
"mark": 999
},
{
"name": "whatever",
"mark": 999
}
],
"tutors": [
{
"name": "John",
"phone": 2000,
"status": "father"
},
{
"name": "Anne",
"phone": 200000,
"status": "mother"
}
],
"exams": [
{
"id": "exam1",
"file": "file"
},
{
"id": "exam2",
"file": "file"
},
{
"id": "exam3",
"file": "file"
}
]
}
notice that I have simplified the json a lot, the nested fields have way more fields. I have two questions:
Is this a proper way to model Mongodb one to many relationships and how do I avoid such long json documents without splitting into more documents?
Isn't it a performance issue that I have to go through all the students just to get subjects for example?
I'm trying to make a query on MongoDB 3.4 where I add a field for one specific element of an array. Example of the object:
{
"_id": 1,
"people": [
{
"name": "Jhon Smith",
"age": "30",
"state": "NY"
},{
"name": "Clint Mercer",
"age": "50",
"state": "NY"
},{
"name": "Walter Smith",
"age": "40",
"state": "WI"
}
]
}
And I want to make a query where I'll add to this document an attribute with the first person with "Smith" in it's name. Example:
{
"_id": 1,
"people": [
{
"name": "Jhon Smith",
"age": "30",
"state": "NY"
},{
"name": "Clint Mercer",
"age": "50",
"state": "NY"
},{
"name": "Walter Smith",
"age": "40",
"state": "WI"
}
],
"firstSmith": {
"name": "Jhon Smith",
"age": "30",
"state": "NY"
}
}
I already have the _id of the document I want, but I can't understand how to make a query like this. I'm trying using aggregate with "$match" for the id and "$addFields" after, but I can't make a query that works for this field to find exactly what I want. I think it would be similar to the "findOne" query, but I can't find anything that works on "$addFields".
Obs: I DON'T want the "firstSmith" to be an array with just one "people" inside, I want it as is in the example.
I'd appreciate some help with this one.
$match - to filter the relevant document
$filter with $regexMatch - to filter people array by the name property
arrayElemAt - to get only the first element of above array
$addFields - to add new field with value from above result
db.collection.aggregate([
{
"$match": {
"_id": 1
}
},
{
"$addFields": {
"firstSmith": {
"$arrayElemAt": [
{
"$filter": {
"input": "$people",
"cond": {
"$regexMatch": {
"input": "$$this.name",
"regex": "Smith"
}
}
}
},
0
]
}
}
}
])
Working example
For the below document, I want to write mongodb query to get the result.
[{
"id": "1",
"class": "class1",
"value": "xyz"
}, {
"id": "2",
"class": "class2",
"value": "abc"
}, {
"id": "3",
"class": "class3",
"value": "123"
}, {
"id": "4",
"class": "class4"
}, {
"id": "5",
"class": "class5",
"value": ""
}
]
The search parameter is an array of values - ["abc", "xyz", ""] and this is
going to look attribute "value"
The output should be below and in this case, the third item in the search array "" is pointing to collection that has "id" - 4 and 5 :
[{
"id": "1",
"class": "class1",
"value": "xyz"
}, {
"id": "2",
"class": "class2",
"value": "abc"
}, {
"id": "4",
"class": "class4"
}, {
"id": "5",
"class": "class5",
"value": ""
}
]
Please assist to provide the mongodb query to get the result like this
Whenever you have blank string you can add null in array, like this,
db.collection.find({
value: {
$in: ["abc", "xyz", "", null]
}
})
I'm using Netsuite's Postman collection (which takes care of the Oauth1 stuff), and am POSTing to this endpoint:
{{proto}}://{{host}}/rest/platform/{{version}}/record/salesorder
... and the body is something like this:
{
"customForm": "999",
"entity": {
"id": "1111"
},
"department": {
"id": "2222"
},
"subsidiary": {
"id": "33"
},
"otherRefNum": "TEST-PO",
"location": {
"id": "444"
},
"item": {
"items": [
{
"item": { "id": "555555" },
"inventorylocation": { "id": "444" },
"price": { "id": "-1" },
"grossAmt": 999,
"quantity": 1
}
]
}
}
I'm trying to assign a location on the item level. The above request creates a sales order ok (without the line-level location assignment) if I remove the inventorylocation line, but with that in there, I get this error: Unknown reference or subrecord field inventorylocation in request body.
Netsuite's REST API documentation is here:
https://system.netsuite.com/help/helpcenter/en_US/APIs/REST_API_Browser/record/v1/2019.2/index.html#tag-salesorder
I have also tried substituting location and moving the fields around a bit, without success. (either the salesorder is created without a line-level location assignment, or I get an error similar to the above error.
Any ideas?
From the documentation you linked, it appears that the field id you need is inventorylocation rather than itemlocation.
salesorder-itemElement
...
giftCertRecipientName Recipient Name: string
id [Missing Label:id]: string
inventorydetail: salesorder-item-inventorydetail
inventorylocation: location
inventorysubsidiary: subsidiary
isClosed Closed: boolean
...
Based on the documentation for a salesOrder-itemElement, it looks like that key is correct.
Have you tried the "location": "{ID}" variation?
In LedgerSync it looks like the request for creating an invoice results in this body:
{
"entity": "309",
"location": "1",
"sublist": {
"items": [
{
"amount": 12345,
"description": "Test Line Item FLURYAOLJLFADYGR-1"
},
{
"amount": 12345,
"description": "Test Line Item FLURYAOLUFUTBYJD-2"
}
]
}
}
There also is a salesOrder-item-inventorydetail object that also contains a location. Perhaps you could use that one like so:
{
"customForm": "999",
"entity": {
"id": "1111"
},
"department": {
"id": "2222"
},
"subsidiary": {
"id": "33"
},
"otherRefNum": "TEST-PO",
"location": {
"id": "444"
},
"item": {
"items": [
{
"item": { "id": "555555" },
"inventorydetail": {
"location": "444"
},
"price": { "id": "-1" },
"grossAmt": 999,
"quantity": 1
}
]
}
}
{
"_id": ObjectId("4ed8d496c605da94400001e4"),
"status": 1,
"user": {
"uid": 1
},
"nid": 10582,
"form": {
"your-name": "Bob Smith",
"description": "",
"photo": "",
"address": "123 Turk Hill Rd",
"city": "",
"zip": "14450"
},
"location": {
"address": "123 Turk Hill Rd",
"city": "",
"zip": "14450",
"geo_lat": 43.0329181,
"geo_lng": -77.4391148,
"address_confirmed": "123 Turk Hill Rd, Victor, NY 14564, USA",
"address_status": 200,
"accuracy": 8
},
"keywords": {
"0": "bob",
"1": "smith",
"2": "",
"4": "123",
"5": "turk",
"6": "hill",
"7": "rd",
"9": "14450"
},
"time": ISODate("2011-12-02T13: 37: 26.0Z")
Search:
{
nid: 10582,
keywords: {"$in": ['turk']}
}
Results: none!
What am I doing wrong?
Answer is simple: because of keywords is not an array. To search on keywords you need to change document structure as follow:
{
...
"keywords": [
"bob",
"smith",
"123",
"turk",
"hill",
"rd",
"14450"
],
...
}
It usually happens when you from driver serialize dictionary. In current moment there is no way to search in such structure. Simple use arrays instead of dictionaries. Or you can convert dictionary to array before serialize document and viсe versa when deserialize document.