I'm trying to query MongoDB for all documents that have a specific key inside a document's nested map
{
"_id" : ObjectId("5a5cd9711736c32c45f11adf"),
"name" : "Test A",
"userSubscription" : {
"map" : {
"1234" : true,
"999" : true,
}
}
}
I'm querying as follows:
db.getCollection('myColl').find( { "userSubscription.map" : {"1234":true }})
It's working, but, it return only documents that holds a single value of "1234", So if "userSubscription.map" contains "1234" and "5555" the query not showing any results.
I'm using Robo3T to test queries, and SpringBoot annotations to query this,
Can the answer be in Spring Boot annotation query?
Spring Boot query example:
#Query("{QUERY : ?0}")
List<Person> findByUserSubscription(String key);
** The "?0" is to use the first method param
Thanks!!!
UPDATE:
Now the document looks like this:
{
"_id" : ObjectId("5a5cd9711736c32c45f11adf"),
"name" : "Test A",
"userSubscription" : {
"1234" : true,
"3333" : true
}
}
Robo 3T Query: db.getCollection('Person').find({ "userSubscription.1234": {$exists : true} })
Works PERFECT!
But, The query in Spring boot looks like:
#Query("{userSubscription.?0 : {$exists: true} }")
and it doesn't show any results...
What is the problem???
Model the map as array of embedded documents like
{
"map" : [
{k: "1234", v: true},
{k: "999", v: true}
]
}
and you can find by key
db.myColl.find({"userSubscription.map":{$elemMatch: { k: "1234", v: true } } })
and
#Query("{'userSubscription.map':{$elemMatch: { k: ?0, v: true } } }")
List<Person> findByUserSubscription(String key);
`
there is a more simple solution with using Query and Criteria Class in Spring Data mongodb. like below:
Query query = new Query();
query.addCriteria(Criteria.where("userSubscription."+key).exists(true));
return mongoTemplate.find(query, YourDocument.class);
You missed single quote for #Query.
#Query("{'userSubscription.?0' : {$exists: true} }")
Related
I am totally new to groovy script and would like some help to solve this out. I have a JSON response I want to manipulate and get desired parameters back by avoiding duplication. The Json response does not have indexes like 0,1,2.. that I can iterate through.
Here is the response that I want to work with:
{
"AuthenticateV2" : {
"displayName" : "Verification of authentication",
"description" : "notification ",
"smsTemplate" : "authentication.v2.0_sms",
"emailHeaderTemplate" : "v2.0_header",
"emailBodyTemplate" : "html",
"parameters" : {
"displayName" : "USER_DISPLAY_NAME",
"actionTokenURL" : "VERIFICATION_LINK",
"customToken" : "VERIFICATION_CODE"
},
"supportedPlans" : [
"connectGo"
]
},
"PasswordRecovery" : {
"displayName" : "Verification of password recovery",
"description" : "notification",
"smsTemplate" : "recovery.v1.0_sms",
"emailHeaderTemplate" : "recovery.v1.0_header",
"emailBodyTemplate" : "recovery.v1.0_body_html",
"parameters" : {
"displayName" : "USER_DISPLAY_NAME",
"actionTokenURL" : "VERIFICATION_LINK",
"customToken" : "VERIFICATION_CODE",
"adminInitiated" : false,
"authnId" : "AUTHENTICATION_IDENTIFIER",
"authnType" : "EMAIL",
"user" : {
"displayName" : "USER_DISPLAY_NAME"
}
},
"supportedPlans" : [
"connectGo"
]
},
"PasswordReset" : {
"displayName" : "password reset",
"description" : "notification",
"smsTemplate" : "recovery.v1.0_sms",
"emailHeaderTemplate" : "recovery.v1.0_header",
"emailBodyTemplate" : "html",
"parameters" : {
"displayName" : "USER_DISPLAY_NAME",
"user" : {
"displayName" : "USER_DISPLAY_NAME"
}
}
The expected output that I want to have:
{
"displayName" : "USER_DISPLAY_NAME",
"actionTokenURL" : "VERIFICATION_LINK",
"customToken" : "VERIFICATION_CODE",
"customToken" : "VERIFICATION_CODE",
"adminInitiated" : false,
"authnId" : "AUTHENTICATION_IDENTIFIER",
"authnType" : "EMAIL"
}
I need to retrieve all fields under parameters tag and also want to avoid duplication
You should first get familiar with parsing and producing JSON in Groovy.
Then, assuming the provided response is a valid JSON (it's not - there are 2 closing curlies (}) missing at the end) to get all the parameters keys merged into one JSON we have to convert the JSON string into a Map object first using JsonSlurper:
def validJsonResponse = '<your valid JSON string>'
Map parsedResponse = new JsonSlurper().parseText(validJsonResponse) as Map
Now, when we have a parsedResponse map we can iterate over all the root items in the response and transform them into the desired form (which is all the unique parameters keys) using Map::collectEntries method:
Map uniqueParameters = parsedResponse.collectEntries { it.value['parameters'] }
Finally, we can convert the uniqueParameters result back into a pretty printed JSON string using JsonOuput:
println JsonOutput.prettyPrint(JsonOutput.toJson(uniqueParameters))
After applying all the above we'll get the output
{
"displayName": "USER_DISPLAY_NAME",
"actionTokenURL": "VERIFICATION_LINK",
"customToken": "VERIFICATION_CODE",
"adminInitiated": false,
"authnId": "AUTHENTICATION_IDENTIFIER",
"authnType": "EMAIL",
"user": {
"displayName": "USER_DISPLAY_NAME"
}
}
If you want to get rid of user entry from the final output just remove it from the resulting uniqueParameters map (uniqueParameters.remove('user')) before converting it back to JSON string.
From the below JSON data, I want to cut out the attributes object and keep only Name of the Account. Sample JSON
{
"Accounts":[
{
"attributes":{
"type":"Account",
"url":"/services/data/v41.0/sobjects/Account/001S0000008mgjpIAA"
},
"Name":"Name+Test#Reseller"
},
{
"attributes":{
"type":"Account",
"url":"/services/data/v41.0/sobjects/Account/001S000000m5gyuIAA"
},
"Name":"Test Reseller Myself"
}
]
}
After matching with REGEX and replacing with "". The JSON should look like,
{
"Accounts" : [{
"Name" : "Name+Test#Reseller"
}, {
"Name" : "Test Reseller Myself"
}]
}
Use map and return only name property value
obj.accounts = obj.accounts.map( s => {Name: s.Name } );
I found myself an answer. I constructed a two regex
1. "attributes" : {\w*\W*\d*\D*\d*.\d*\D*\w*"\w*
2. {.\s*\S*
I try to build a json for me to test my firebase application. I need a couple of hundred entries and for that reason try to build me json with the JSON Generator from https://www.json-generator.com/
How ever I have problems to get random IDs as keys (and not as values). I tried all I can think of with {{objectId()}} but this seem to work only for values.
Does anybody have an idea how I could build a RANDOM JSON like the example below with the JSON Generator I used or any other generator? Again the problem is the random KEYS! As values this works great.
here an example of the JSON i need at the end.
{
"-f2zawhcNgh6vcHIQOCq" : {
"cat_id" : 1,
"created_at" : 1516206514529,
"edited_at" : 1516206514529,
"groups" : {
"-L2zawhcNgh6vcHIQOCq" : true,
"-L2zaxyBs-9AfQJii47k" : true
},
"local" : true,
"owner_id" : "MyaNhS4Qy6foMYkSIt0tpRQFneI3",
"private" : false
},
"-fghgajhgfkjhkQOCq" : {
"cat_id" : 1,
"created_at" : 1516206514529,
"edited_at" : 1516206514529,
"groups" : {
"-L2zawkjhfkjhkjgQOCq" : true
},
"local" : true,
"owner_id" : "hgfjhYkSIt0tpRQFneI3",
"private" : false
}
}
JSON.stringify(new Array(200).fill('something').reduce(mock => {
mock[Math.random()] = {
"cat_id" : 1,
"created_at" : Date.now()*Math.random() | 0,
"edited_at" : Date.now(),
"groups" : {
[Math.random()] : true
},
"local" : true,
"owner_id" : Math.random(),
"private" : false
}
return mock
}, {}), undefined, 2)
Paste this in chrome js console or node.js
Is that what you are looking for?
I have a json document like this on my mongodb collection:
Updated document:
{
"_id" : ObjectId("59da4aef8c5d757027a5a614"),
"input" : "hi",
"output" : "Hi. How can I help you?",
"intent" : "[{\"intent\":\"greeting\",\"confidence\":0.8154089450836182}]",
"entities" : "[]",
"context" : "{\"conversation_id\":\"48181e58-dd51-405a-bb00-c875c01afa0a\",\"system\":{\"dialog_stack\":[{\"dialog_node\":\"root\"}],\"dialog_turn_counter\":1,\"dialog_request_counter\":1,\"_node_output_map\":{\"node_5_1505291032665\":[0]},\"branch_exited\":true,\"branch_exited_reason\":\"completed\"}}",
"user_id" : "50001",
"time_in" : ISODate("2017-10-08T15:57:32.000Z"),
"time_out" : ISODate("2017-10-08T15:57:35.000Z"),
"reaction" : "1"
}
I need to perform group by on intent.intent field and I'm using Rstudio with mongolite library.
What I have tried is :
pp = '[{"$unwind": "$intent"},{"$group":{"_id":"$intent.intent", "count": {"$sum":1} }}]'
stats <- chat$aggregate(
pipeline=pp,
options = '{"allowDiskUse":true}'
)
print(stats)
But it's not working, output for above code is
_id count
1 NA 727
If intent attribute type is string and keep the object as string.
We can split it to array with \" and use third item of array.
db.getCollection('test1').aggregate([
{ "$project": { intent_text : { $arrayElemAt : [ { $split: ["$intent", "\""] } ,3 ] } } },
{ "$group": {"_id": "$intent_text" , "count": {"$sum":1} }}
])
Result:
{
"_id" : "greeting",
"count" : 1.0
}
I have a mongo json object as follows
{
"_id" : new BinData(3, "RDHABb22XESWvP83FplqJw=="),
"name" : "NEW NODE",
"host" : null,
"aet" : null,
"studies" : ["1.3.12.2.1107.5.99.3.30000008061114424970500000589"],
"testcases" : [new BinData(3, "Zhl+zIXomkqAd8NIkRiTjQ==")],
"sendentries" : [{
"_id" : "1.3.12.2.1107.5.99.3.30000008061114424970500000589",
"Index" : 0,
"Type" : "Study"
}, {
"_id" : "cc7e1966-e885-4a9a-8077-c3489118938d",
"Index" : 1,
"Type" : "TestCase"
}]
}
The fields "Studies" and "TestCases" are now obsolete and I am now storing that information in a new field called SendEntries. I would like to get rid of the Studies and TestCases from the old entries and unmap those fields going forward. I want to know how I can update my current collections to get rid of the Studies and TestCases fields.
I'm just few weeks into Mongo.
You can use the $unset operator with update.
db.collection.update({},
{ $unset: {
"studies": "",
"testcases": ""
},
{ "upsert": false, "muti": true }
)
And that will remove all of the fields from all of your documents in your collection
Use $unset, there's a manual page e.g.
db.yourCollection.update( { },
{ $unset: {
Studies: "",
testcases: ""
}
},
{ multi: true }
)