I have a dynamic complex JSON, something like this
var source = [{
"ab" : 123,
"xfg" : {
"cdf" : "xyz",
"e" : [{"aaa" : "bbb"}, {"ccc" : "ccc"}]
},
"mno" : ["fff", "123"]
}];
How can I extract data from this JSON using some dynamic expressions in a given search object:
var search= {
"search1" : "ab",
"search2" : "xfg.cdf",
"search3" : "ccc value in xfg.e?",
}
Basically, I can analyze the type of each element in the search object, if it's a string split it by '.' separator and then access the elements in the source object...
But what about complex search expressions? How do I get the 'ccc' value for example?. Is there a way to implement complex search expressions? something like in mongodb find function?
Thanks
I haven't used this, but the demo looks really nice. It's basically a css type selector for JSON: JSONSelect.
For a more XPath style, try JSONPath, which also looks very capable. JSONPath
Both are Javascript libraries and are easily included in your project.
Related
I have a file that includes (schemaless) JSON Lines encoded data.
For example:
{"foo" : "abc", "bar" : "def" }
{"foo" : "xyz" }
{"foo" : "ghi", "bar" : "jkl", "name" : "The Dude"}
I would like to use NIFI to convert this into a JSON array:
[{"foo" : "abc", "bar" : "def" },{"foo" : "xyz" },{"foo" : "ghi", "bar" : "jkl", "name" : "The Dude"}]
The easiest way to accomplish this in Apache NiFi is to use two ReplaceText processors. In the first, configure as:
Search Value: \}\s*\{
Replacement Value: \},\{
Replacement Strategy: Regex Replace
Evaluation Mode: Entire Text
This will remove the line breaks between the tuples and insert commas between them. In the second:
Search Value: (^.*$)
Replacement Value: [$1]
Replacement Strategy: Regex Replace
Evaluation Mode: Entire Text
This will add the enclosing brackets around the JSON array. There are other ways to accomplish this with ExecuteScript or JoltTransformJSON processors, but they are more complicated and brittle.
I have mongodb data model where I have some array fields that contain embedded objects or arrays. I have some inconsistencies in the field in question because I've tweaked my application logic. Initially, my model looked like this:
Initial Setup of Results collection
"competition" : "competition1",
"stats" : [
{
"stat1" : [],
"stat2" : []
}
]
However, I saw that this wasn't the best setup for my needs. So I changed it to the following:
New Setup of Results collection
"competition" : "competition1",
"stats" : [
{
"stat1" : 3,
"stat2" : 2
}
]
My problem now is that documents that have the initial setup cause an error. So what I want is to find all documents that have the initial setup and convert them to have the new setup.
How can I accomplish this in mongodb?
Here is what I've tried, but I'm stuck...
db.getCollection('results').find({"stats.0": { "$exists": true }})
But what I want is to be able to do something like
db.getCollection('results').find({"stats.0".stat1: { "$type": Array}})
Basically I want to get documents where the value of stats[0].stat1 is of type array and override the entire stats field to be an empty array.
This would fix the errors I'm getting.
$type operator for arrays in older versions works little differently than what you might think than $type in 3.6.
This will work in 3.6
db.getCollection('results').find( { "stats.0.stat1" : { $type: "array" } } )
You can do it couple of ways for lower versions and It depends what you are looking for.
For empty arrays you can just check
{"stats.0.stat1":{$size:0}}
For non empty arrays
{"stats.0.stat1": {$elemMatch:{ "$exists": true }}}
Combine both using $or for finding both empty and non empty array.
For your use case you can use below update
db.getCollection('results').update({"stats.0.stat1":{$size:0}}, {$set:{"stats":[]}})
I'm very new to MongoDB and experience some difficulties in importing data into the database. Now I have a collection of documents which looks like
db.Question.findOne()
{
"_id" : ObjectId("124"),
"Answers" : "[\"502\",\"784\",\"1060\"]",
}
The Answers are now stored as a single string. However I want to convert it to a list like below so I could unwind it when doing query.
{
"_id" : ObjectId("124"),
"Answers" : ["502","784","1060"],
}
Any idea how to do it ? Thanks.
You can use JSON.parse() to change string type to list and then save the collection with update element. Below is a example:
db.Question.find({}).snapshot().forEach(function (el){el.Answers=JSON.parse(el.Answers);db.Question.save(el)});
You simply need to apply JSON.parse to each of these strings:
> JSON.parse("[\"502\",\"784\",\"1060\"]")
[ '502', '784', '1060' ]
First remove "[" and "]" in the data, then use below code, which create a new attribute,answers, which is a array/list that holds individual numbers:
db.Question.find({}).snapshot().forEach(function (el) {
el.answers=el.Answers.substring(1,el.Answers.length-1);
el.answers = el.Answers.split(',');
db.Question.save(el);
});
So in my MongoDB Collection I have this structure:
"_id" : "Object("-----------")
"name" : "John Doe"
"tool" : {
"hammer" : {
"name" : "hammer 1",
"characteristics" : [
{
"length" : "9 inches"
},
{
"weight" : "4 pounds"
}
]
I know the data may seem a little strange but I can't put the actual data online so I had to input some dummy data. So essentially what I would like to do is be able to update the array that is nested within those objects. So I would like to be able to update the weight or add a new characteristic that I haven't previously entered into it. So for example, add in "metal" : "steel" as a new entry into the array. Currently I'm using a Rest API built in Node.js and Express.js to edit the db. When I was trying to figure out how to dig down this deep I was able to do it with an array at the highest level, however I haven't been able to figure out how to access an array when its embedded like this. So what I was wondering if anybody knew if it was even possible to edit an array this far down? I can post code from controller.js and server.js file if needed but I figured I'd see if it's even possible to do before I start posting it. Any help would be greatly appreciated!
You can use findAndModify to $push it into the array. You have to specify the path precisely though:
db.tools.findAndModify( {
query: { name: "John Doe"},
update: { $push: { tool.hammer.characteristics: {metal: "steel"} }
} );
If I have a field in a mongodb document which has an array, for example:
"tags" : [ "tag", "etc1", "etc2", "etc3" ]
Is there a way that I can select that document if it contains the element 'etc1'?
If I try using the query:
db.coll.find({"tags" : { $elemMatch: { value0: 'etc1'} }})
but I need to know the position of the element in the array, which I don't know.
I have also tried:
db.coll.find({"tags" : { $elemMatch: 'etc1' }})
but it needs to be an object. Is there any way of doing this?
NB I am using mongoose but I wasn't sure how to construct the query
Use the $in operator as described in this question or this other question and as described in the mongodb docs and can be accessed in mongoose.
With it, you'll have a query that looks something like this...remembering that you must pass an array when using $in:
db.coll.find({"tags" : { $in : ['etc1'] } } );
Apart from using $in operator you can also use $all operator like:
db.col1.find({"tags":{$all :["etc1"]}})