Check for value in json array - postgresql

I have a table of data which has a field called details which contains a json object.
The object looks something like this:
{
"name": "Persons Name",
"list": [
{
"name": "Persons Name",
"assigned": {
"company": "Company 1",
"number": "AA1"
}
},
{
"name": "Persons Name",
"assigned": {
"company": "Company 2",
"number": "BB2"
}
},
{
"name": "Persons Name",
"assigned": {
"company": "Company 3",
"number": "AA3"
}
}
],
"total_results": 3
}
Essentially, I want to return all data if any of the person's 'assigned'->>'number' field begins with an A. In the above example, two of the individuals numbers are prefixed with an A so I want all data returned.
I've been playing around and had have been making some progress but can't figure out how to bring it all together.
select f->'assigned'->>'number' from jsonb_array_elements((select details->'list' from table_name)) f;
The above query can get me a list of the three 'number' fields but I'm not sure how I can combine that with a query to return all the information, if any of these fields contain a prefix A

You are so close. Just add your condition in where clause.
SELECT *
FROM JSON_ARRAY_ELEMENTS((SELECT details -> 'list' FROM TABLE_NAME)) f
WHERE f -> 'assigned' ->> 'number' LIKE 'A%'
CHECK DEMO HERE

Related

Mongoose hide fields AFTER populating

Supposed I have this schema
class Room {
member_ids: [String]
owner_ids: [String]
}
And two virtual populates members and owners, which map to User schema (custom path, not _id)
I successfully get the data populated with this:
return this.roomModel
.findOne({ id: roomId })
.select('-_id -__v')
.populate('members owners', '-_id -__v')
.exec();
It now returns
{
"member_ids": [
"1",
"2"
],
"owner_ids": [
"1"
],
"owners": [
{
"id": "1",
"name": "User 1"
}
],
"members": [
{
"id": "1",
"name": "User 1"
},
{
"id": "2",
"name": "User 2"
}
]
}
The thing is, I don't want member_ids and owner_ids to end up in my response. I've tried using select('-member_ids -owner_ids') however the response did not have populated data anymore (I guess the select phase happens before the populate phase?). Is there anyway to achieve this, without resorting to manually removing the fields afterwards? Thank you.

How to get two same attribute in azure cosmos db

I am creating a service using cosmos db.I am trying to creating a search query.
Query :
SELECT product.Name,product1.Name
FROM catalog
join industry in catalog.Industy
join category in industry.Category
join product1 in category.Product
join Subcategory in category.Subcategory
join product in Subcategory.Product
WHERE CONTAINS(product1.Name,'dg')
But i can not able to get both product and product list . it give me the error. Name already used.
error:
Object creation error, property name 'Name' specified more than once
Tree that i am trying to fetch :
[
{
"id": "string",
"industy": [
{
"id": "string",
"category": [
{
"id": "string",
"subcategory": [
{
"id": "string",
"product": [
{
"id": "string",
"methodOfPreparation": [
{
"id": "string",
}
],
"addons": [
{
"id": "string"
}
]
}
]
}
],
"product": [
{
"id": "string",
"methodOfPreparation": [
{
"id": "string"
}
],
"addons": [
{
"id": "string"
}
]
}
]
}
]
}
]
}
]
expect Output
product[],prodcut1[]
How can i solve this?
Firstly, the error could be solved if you use alias as #Zohar mentioned in the comment.
SELECT product.Name as productName,product1.Name as product1Name
FROM catalog
join industry in catalog.industy
join category in industry.category
join product1 in category.product
join Subcategory in category.subcategory
join product in Subcategory.product
The reason is that every retrieved item is an obj, the format of results is an array consists of many objects. The object can't accept duplicate column names.
If you want to get the format like product[],prodcut1[],you need to loop the result and assemble by yourself.(For example,use stored procedure)

MongoDB: replace full object in array [duplicate]

This question already has answers here:
How do I update Array Elements matching criteria in a MongoDB document?
(2 answers)
How to update a subdocument in mongodb
(1 answer)
Closed 5 years ago.
I was looking through StackOverflow, but most of the questions are related to updating of a single element of the object from the array.
In my case, I have a little different situation.
I want to replace full object from an array with a new one.
The original collection looks like:
db.countries.find().pretty()
{
"_id": "some ID goes here",
"longitude": "some longitude",
"latitude": "some latitude",
"name": "name of some country",
"millionaires": [
{"millionaire_id": "ID of the first millionaire",
"name": "name of the first millionaire",
"money": 12000000,
},
{"millionaire_id": "ID of the second millionaire",
"name": "name of the second millionaire",
"money": 15000000,
},
],
}
Then for some reason, I want to replace some data for the first millionaire(amount of money changed, etc.). NOTE: I don't know which field changed.
I'm trying to do something like this:
db.countries.update({"_id": "country ID",
"millionaires.millionaire_id": "ID of the first millionaire"
},
{$set: {
"millionaire_id": "the same millionaire ID",
"value": "should be another value", ...
}
})
But that works unexpectedly:
db.countries.find().pretty();
{
"_id": "some ID goes here",
"longitude": "some longitude",
"latitude": "some latitude",
"name": "name of some country",
"millionaires": [
{"millionaire_id": "ID of the first millionaire",
"name": "name of the first millionaire",
"money": 12000000,
},
{"millionaire_id": "ID of the second millionaire",
"name": "name of the second millionaire",
"money": 15000000,
},
],
{
"millionaire_id": "the same millionaire ID",
"value": "should be another value", ...
}
}
So, it added a new object out of my list of millionaires.
NOTE: objects for updates go programmatically that's why it's not a good idea to try something like this:
new_object = {"millionaires. millionaire_id": "ID", "millionaires.name": "name", ...}
I have raw objects and want to update existing elements using this objects.
Any ideas?

How can I query an indexed object list in mongodb?

I have some documents in the "company" collection structured this way :
[
{
"company_name": "Company 1",
"contacts": {
"main": {
"email": "main#company1.com",
"name": "Mainuser"
},
"store1": {
"email": "store1#company1.com",
"name": "Store1 user"
},
"store2": {
"email": "store2#company1.com",
"name": "Store2 user"
}
}
},
{
"company_name": "Company 2",
"contacts": {
"main": {
"email": "main#company2.com",
"name": "Mainuser"
},
"store1": {
"email": "store1#company2.com",
"name": "Store1 user"
},
"store2": {
"email": "store2#company2.com",
"name": "Store2 user"
}
}
}
]
I'm trying to retrieve the doc that have store1#company2.com as a contact but cannot find how to query a specific value of a specific propertie of an "indexed" list of objects.
My feeling is that the contacts lists should not not be indexed resulting in the following structure :
{
"company_name": "Company 1",
"contacts": [
{
"email": "main#company1.com",
"name": "Mainuser",
"label": "main"
},
{
"email": "store1#company1.com",
"name": "Store1 user",
"label": "store1"
},
{
"email": "store2#company1.com",
"name": "Store2 user",
"label": "store2"
}
]
}
This way I can retrieve matching documents through the following request :
db.company.find({"contacts.email":"main#company1.com"})
But is there anyway to do a similar request on document using the previous structure ?
Thanks a lot for your answers!
P.S. : same question for documents structured this way :
{
"company_name": "Company 1",
"contacts": {
"0": {
"email": "main#company1.com",
"name": "Mainuser"
},
"4": {
"email": "store1#company1.com",
"name": "Store1 user"
},
"1": {
"email": "store2#company1.com",
"name": "Store2 user"
}
}
}
Short answer: yes, they can be queried but it's probably not what you want and it's not going to be really efficient.
The document structure in the first and third block is basically the same - you have an embedded document. The only difference between are the name of the keys in the contacts object.
To query document with that kind of structure you will have to do a query like this:
db.company.find({ $or : [
{"contacts.main.email":"main#company1.com"},
{"contacts.store1.email":"main#company1.com"},
{"contacts.store2.email":"main#company1.com"}
]});
This query will not be efficient, especially if you have a lot of keys in the contacts object. Also, creating a query will be unnecessarily difficult and error prone.
The second document structure, with an array of embedded objects, is optimal. You can create a multikey index on the contacts array which will make your query faster. The bonus is that you can use a short and simple query.
I think the easiest is really to shape your document using the structure describe in your 2nd example : (I have not fixed the JSON)
{
"company_name": "Company 1",
"contacts":{[
{"email":"main#company1.com","name":"Mainuser", "label": "main", ...}
{"email":"store1#company1.com","name":"Store1 user", "label": "store1",...}
{"email":"store2#company1.com","name":"Store2 user", "label": "store2",...}
]}
}
like that you can easily query on email independently of the "label".
So if you really want to use the other structure, (but you need to fix the JSON too) you will have to write more complex code/aggregation pipeline, since we do not know the name and number of attributes when querying the system. Theses structures are also probably hard to use by the developers independently of MongoDB queries.
Since it was not clear let me show what I have in mind
db.company.save(
{
"company_name": "Company 1",
"contacts":[
{"email":"main#company1.com","name":"Mainuser", "label": "main"},
{"email":"store1#company1.com","name":"Store1 user", "label": "store1"},
{"email":"store2#company1.com","name":"Store2 user", "label": "store2"}
]
}
);
db.company.save(
{
"company_name": "Company 2",
"contacts":[
{"email":"main#company2.com","name":"Mainuser", "label": "main"},
{"email":"store1#company2.com","name":"Store1 user", "label": "store1"},
{"email":"store2#company2.com","name":"Store2 user", "label": "store2"}
]
}
);
db.company.ensureIndex( { "contacts.email" : 1 } );
db.company.find( { "contacts.email" : "store1#company2.com" } );
This allows you to store many emails, and query with an index.

extjs nested data view select a node

i have data view with following tpl.
<tpl for=".">
<tpl for="departments">
{title}
</tpl>
<tpl for="records">
<div class="thumb-wrap">
{name}
</div>
</tpl>
</tpl>
and my json redear like this
reader : new Ext.data.JsonReader(
{
root : 'data',
},
[
'departments' ,
'records'
]
),
and my item selectore in on my recordes
itemSelector : 'div.thumb-wrap',
and this is my json data
{
"success": true,
"data": [
{
"departments": [
{
"title": "name"
}
],
"records": [
{
"name": "name"
},
{
"name": "name"
}
]
},
{
"departments": [
{
"title": "name"
}
],
"records": [
{
"name": "name"
}
]
}
]
}
how cat i select my records in data view with extjs?
and how can i get selected recordes ?
i used getSelectedRecords() but it return array of departments and records.
tnx
I'm pretty sure that getSelectedRecords() is deprecated on ExtJS 4.
You can try doing something like this:
var records = data.getRecords();
That will return a Ext.data.Model[]. Than, you can access all the properties like an usual model:
record.get('departments');
record.get('records');
You are working against the system here with your record structure. DataView wants one record to correspond with one selectable item. But you want to have multiple selectable items inside one record. Doesn't work - the API was not designed for such a thing.
Your options seem to be:
Create a separate DataView component for each set of records.
Create your own DataView component that can handle grouping.
Use Grid with GroupingView. You have to change your record structure to something like below, but it's the easiest option to get working. Though... you have to sacrifice quite a bit of flexibility offered by DataView.
"data": [
{
{
"department": "Department 1"
"name": "record 1"
},
{
"department": "Department 1"
"name": "record 2"
},
{
"department": "Department 2"
"name": "record 1"
},
{
"department": "Department 2"
"name": "record 2"
},
]
}