I have a rather complex structure on my json and I cannot find how to query it to get the rows I am interested in. Here is a sample of my data:
{
"_id" : ObjectId("5282bf9ce4b05216ca1b68f8"),
"authorID" : ObjectId("5282a8c3e4b0d7f4f4d07b9a"),
"blogID" : "7180831558698033600",
"blogs" : {
"$" : {
"posts" : [
[
{
"author" : {
"displayName" : "mms",
...
...
...
}}}
So, I am interested in finding all json entries that have the author displayName equal to "mms".
My collection name is bz so, a find all query would be: db.dz.find()
What criteria do I have to put inside the find() to only get json document with author displayName equal to mms?
Any ideas?
Thank you in advance!
Suppose you have replaced field name "$" with "dollarSign".
Then db.dz.find({"blogs.dollarSign.posts.author.displayName": "mms"}) will fetch whole documents according to your requirements.
Related
I'm having a problem with querying a MongoDB dataset ("On Street Crime in Camden" from data.gov.uk)
The database name is Crime_Data_in_Camden and the collection name is Street_Crime_Camden. The query to find all records, db.Street_Crime_Camden.find(), works fine but anything else returns nothing at
all. Here is a portion of the metadata:
{
"id" : 509935,
"name" : "Ward Name",
"dataTypeName" : "text",
"fieldName" : "ward_name",
"position" : 13,
"renderTypeName" : "text",
"tableColumnId" : 258836,
"width" : 100,
"cachedContents" : {
"largest" : "West Hampstead",
"non_null" : 79813,
"null" : 0,
"top" : [ {
"item" : "Regent's Park",
"count" : 20
}, {
"item" : "Swiss Cottage",
"count" : 19
}, {
"item" : "Holborn and Covent Garden",
"count" : 18
}
}
}
I've tried 3 attempts at a basic query:
db.Street_Crime_Camden.find({"ward_name":"West Hampstead"});
db.Street_Crime_Camden.find({'meta.ward_name':'West Hampstead'});
db.Street_Crime_Camden.find({meta:{ward_name:"West Hampstead"} });
According to any documentation or tutorial that I've seen any of these approaches should be valid. And I know that there are hundreds of rows (or documents) that match those terms, so why are these queries returning nothing? Advice would be appreciated.
The common theme in the three aproaches you tried is some form of ward_name = West Hampstead but there is no attribute named ward_name in the document you shared with us.
Based on the document you show in your question the only way of addressing an attribute with the value West Hampstead is:
db.Street_Crime_Camden.find({"cachedContents.largest": "West Hampstead"});
For background; you address attributes in your documents by using dot notation so the document you included in your question could be found by any of the following find commands:
db.Street_Crime_Camden.find({"name": "Ward Name"});
db.Street_Crime_Camden.find({"position": 13});
db.Street_Crime_Camden.find({"cachedContents.top.item": "Swiss Cottage"});
db.Street_Crime_Camden.find({"cachedContents.top.1.count": 20});
... etc
These examples might help you to understand how to form find criteria. The MongoDB docs are also useful.
I have a data field that looks like this :
{ "field1" : [{"name":'name1',"value1":true},
{"name":'name2',"value2":false}
],
"field2" : [{"name":'name1',"value1":true},
{"name":'name2',"value2":false}
]
}
Is it possible to update a specific field with an update ?
create table t_json (
t_data json
);
insert into t_json values('{"field1":[{"name":"name1","value" : true},{"name":"name2","value" : false}],"field1":[{"name":"name1","value" : true},{"name":"name2","value" : false}]}');
select t_data->'field1'
from t_json;
I tried this :
update t_json
set t_data->'a' = '[{"value1" : true, "value2" : false}]';
But I get an error : "syntax error at or near ->
What is missing ?
I wanted to post this here in case it helps anybody else. By all means use JSON over JSONB unless you actually need features that JSONB affords you. In general, if you need to perform queries on the JSON data itself, use JSONB. If you are just needing to store data, use JSON.
Anyhow, here is how I am updating a JSON[] field:
UPDATE foo SET bar = ARRAY[$${"hello": "world"}$$, $${"baz": "bing"}$$]::JSON[]
The important things to notice are this:
The array is wrapped like this: ARRAY[ ... ]::JSON[]
Each item in the array is wrapped like this: $${ "foo": "bar" }$$
It is worth noting that this same technique can be used for other array types. For example, if you have a text[] column, the query would look like this:
UPDATE foo SET bar = ARRAY[$$hello world$$, $$baz bing$$]::TEXT[]`
Fixing your typos
Doubt it. This is not valid json. name1 and name2 must be double quoted. To ease working with json, ALWAYS use double quotes. ALWAYS query-quote with double-dollar.
{ "field1" : [{"name":'name1',"value1":true},
{"name":'name2',"value2":false}
],
"field2" : [{"name":'name1',"value1":true},
{"name":'name2',"value2":false}
]
}
And, what you INSERTED is also funky.. ALWAYS paste beautified valid JSON in your question.
{
"field1":[{"name":"name1","value" : true},{"name":"name2","value" : false}],
"field1":[{"name":"name1","value" : true},{"name":"name2","value" : false}]
}
Let's change that and fix it.
{
"field1":[{"name":"name1","value" : true},{"name":"name2","value" : false}],
"field2":[{"name":"name1","value" : true},{"name":"name2","value" : false}]
}
Now let's put it in a query..
TRUNCATE t_json;
INSERT INTO t_json (t_data) VALUES ($$
{
"field1":[{"name":"name1","value" : true},{"name":"name2","value" : false}],
"field2":[{"name":"name1","value" : true},{"name":"name2","value" : false}]
}
$$);
Making the update of the JSON
Now it works.. Now you can update it as you want..
UPDATE t_json
SET t_data = jsonb_set(
t_data::jsonb,
'{field1}',
$${"whatever":1}$$
);
Change from JSON to JSONB
Notice we're having to cast to jsonb. As a general rule, NEVER use JSON (not everyone agrees, see comments). There is no point. Instead use the newer JSONB.
ALTER TABLE t_json ALTER COLUMN t_data TYPE jsonb ;
Now you can do
UPDATE t_json
SET t_data = jsonb_set(
t_data,
'{field1}',
$${"whatever":1}$$
);
This is the structure of a document I have in one monggodb collection.
I wanted to understand how one can do a mongo aggregate of grouped count over key "code" and the index position in the nested json (not the priority as it can be any number but within schedules nested there can be just 5 values):
{
"_id" : ObjectId("5749e9fde4b0064e7362b560"),
"_class" : "com.weirdcompanyname.core.collectionname",
"rfId" : 1,
"scheduleds" : [
{
"code" : "556e4835f1eae40bdfa2f2001f2afc76",
"type" : "HT",
"priority" : 0
},
{
"code" : "8b2ab67af4f60e42f7ea64813b5795cf",
"type" : "HT",
"priority" : 1
},
{
"code" : "ed17101eb918b4d8c7c598e4884523ea",
"type" : "HT",
"priority" : 2
},
{
"code" : "7e0ffb4db",
"type" : "QZ",
"priority" : 3
},
{
"code" : "1453dfa1794f39b05f0259ad04699073",
"type" : "HT",
"priority" : 4
}
],
"created" : ISODate("2016-05-28T18:57:00.878Z")
}
The result I'm trying to find is:
code index_position count
556e4835f1eae40bdfa2f2001f2afc76 0 100
8b2ab67af4f60e42f7ea64813b5795cf 1 100
ed17101eb918b4d8c7c598e4884523ea 2 100
7e0ffb4db 3 100
1453dfa1794f39b05f0259ad04699073 4 100
I could get my head around unwinding the nested json in single arrays and then grouping the code over code and maybe other column, let's say priority and have the count but the problem is to get the index position.
Is this even doable on mongo, I've read around a lot of stuff about it and I figured if I have value for which I need a position then it can be doable but I don't really have a value to look for, what I'm looking for is each code and its index position in the "scheduleds" and count.
This is what I could do with my limited mongo querying skills:
db.collectionname.aggregate([{'$match':{'date_key':{'$gte': yesterday_beginning, '$lte': yesterday_end}}}, {'$unwind':'$scheduleds'}, {'$group':{'_id':{'code':'$scheduleds.code','priority':'$scheduleds.priority'}, 'rfid':{'$addToSet':'$rfId'}}}, {'$project':{'_id':0, 'code':'$_id.code', 'priority':'$_id.priority', 'totalRfid':{'$size':'$rfid'}}}, { $limit : 1000 }],{ allowDiskUse:true})
Alain1405 says here that MongoDB 3.2 supports unwinding of the array index.
Instead of passing a path the $unwind operator, you can pass an
object with the field path and the field includeArrayIndex which
will hold the array index.
From MongoDB official documentation:
{
$unwind:
{
path: <field path>,
includeArrayIndex: <string>,
preserveNullAndEmptyArrays: <boolean>
}
}
I am a newbie to MongoDB. I am experimenting the various ways of extracting fields from a document inside collection.
Here in the below JSON document, I am finding it difficult to get extract it according to my need
{
"_id":1,
"dependencies":{
"a":[
"hello",
"hi"
],
"b":[
"Hmmm"
],
"c":[
"Vanilla",
"Strawberry",
"Pista"
],
"d":[
"Carrot",
"Cauliflower",
"Potato",
"Cabbage"
]
},
"productid":"25",
"date":"Thu Jul 30 11:36:49 PDT 2015"
}
I need to display the following output:
c:[
"Vanilla",
"Strawberry",
"Pista"
]
Can anyone please help me in solving it?
MongoDB Aggregation comes into rescue to get the result you are looking for :
$Project--> Passes along the documents with only the specified fields to the next stage in the pipeline. The specified fields can be existing fields from the input documents or newly computed fields.
db.collection.aggregate( [
{ $project :
{ c: "$dependencies.c", _id : 0 }
}
]).pretty();
As per the output you required, we just need to project ( display) the field "dependencies.c" , so we are creating a new field "c" and assigining the value of the "dependencies.c" into it.
Also by defalut "_id" field will be display along with the result, since you dont need it, so we are suppressing of the _id field by assigining "_id" : <0 or false>, so that it will not display the _id field in the output.
The above query will fetch you the result as below :
"c" : [
"Vanilla",
"Strawberry",
"Pista"
]
I need to retrieve information from a JsValue that may be structured in a few different ways buy the specific values I'm looking for will always be under similar names.
So for example I could have something like:
{
"name" : "Watership Down",
"location" : {
"lat" : 51.235685,
"long" : -1.309197
}
}
OR
{
"title" : "Watership Down",
"size" : "M",
"location" : {
"latitude" : 51.235685,
"longitude" : -1.309197
}
}
and I'd want to be able to do: val text = json \\ "name"|"title"
I know what I want is either under name or title but not sure which in a given scenario. Is there any way to do something similar to what I did above with an "or" similar to Scala's .getOrElse() method?
You can do:
val text = (json \\ "name").asOpt[String]
.getOrElse((json \\ "title").as[String])