How to query data from `PostgresSql`? - postgresql

I use NestJj,PostgreSQL and Graphql for Back-End,
Flutter,graphql_flutter for Front End.
I have a collection store like this :
I want to get the following result:
[
{
type:'A',
details:[
{name:'Food1'}
]
},
{
type:'Expense',
details:[
{name:'gym'},
{name:'Dinner'}
]
},
{
type:'Revenue',
details:[
{name:'Revenue'}
]
}
]
For show on the device :
How can I query?
Could you help me?

I'm not sure if you'll be able to build that structure at the level of SQL.
What you can do is to extract the data from the table wit the structure as it is and then map it at the level of JS.
// here's an example with TypeORM
const data = await Collection.findBy({...});
const result = data.map(item => ({
type: item.type,
details: [{
name: item.name
}]
}));
P.S. I'm pretty sure that's not the answer you've expected but it will solve your issue.

Related

How to target a field in Prisma and get a flat array of values rather than an array of objects

I just started using Primsa 2 so I am still a noob at this but all I am trying to do is create a flat array of strings(Array<number>) based on the values I get from a specific field. Right now when I target that field it gives me an array of objects like this: userIds: [{ issueId: 1, userId: 1 }]
All I want is the value I get from the userId key and the array to return like this userIds: [ 1 ]. I was able to fix this with some formatting code after the query which was done like so:
const issues = project.issues.map(issue => ({ ...issue, userIds: [...issue.userIds.map((id) => id.userId)] }))
const _project = { ...project, issues }
However, this doesn't seem like the most optimal solution. If this is the only way that is fine but I assume with the power that Prisma has for querying, this is something I can do just in the query alone?
For reference, my query currently looks like this:
const project = await prisma.project.findFirst({
where: { id: req.currentUser.projectId },
include: { users: true, issues: { include: { userIds: true } } },
})
Thanks in advance!
Can you show your schema? Perhaps you can model the relation differently. However, unless if you provide a field, userIds, that is a flat array and not a field of a an other relation it will be returned as a list of objects as you have already.

How to map Elasticsearch match_phrase query in flutter

I am trying to add elasticsearch to my flutter app.
I am using elastic_client to deal with the connection
How can I map the following query in flutter format?
POST /books/_search
{
"query": {
"match_phrase": {
"name" : {
"query" : "Roberts book",
"slop": 50
}
}
}
}
There is very little info about elasticsearch and flutter.
Right now I have the following code to do the query with elastic_client. But as far as I understand this package did not have the match_phrase implemented. And I need to query match_phrase.
final searchResult = await client.search(
index: 'books',
type: '_doc',
query: elastic.Query.term('name', ['$searchQuery'.toLowerCase()]),
source: true);
I followed this tutorial if you want to know more.
Update
With the help of #Vlad and the creator of the elastic_client
It might be useful for someone, so the full solution is:
final transport = HttpTransport(url: 'http://myip:9200/');
final client = elastic.Client(transport);
final searchResult = await client.search(
index : 'books',
type: '_doc',
query: {
"match_phrase": {
"name" : {
"query" : '$searchQuery'.toLowerCase(),
"slop": 50,
},
},
});
By following the match implementation source code, it looks like that these methods are just wrappers to create JSON. So based on that, I can derive, that you could do the following:
final searchResult = await client.search(
index: 'books',
type: '_doc',
query: {
'match_phrase': {
'name': {
'query': '$searchQuery'.toLowerCase(),
'slop': 50
}
},
};
source: true);
Note, that I have no experience with Flutter, this is just my thinking based on the source code.
Alternatively, you could create your own method which creates JSON for Elasticsearch.

Sails Waterline "Or" clause not working

I tried a lot of time to figure out getting an OR clause working in sails without success.
I am using Sails-MySql adapter.
Have anyone of you done anything like this already? I would appreciate some help.
Basically this is what I want to do:
Do an OR clause on a set of fields along with an AND on another set of fields.
Something like this:
FdbDevice
.find()
.where(or:
[
{ deviceCategory: “cardiology valve bioprosthesis” },
{ deviceCategory: “nephrology haemodialysis catheter” }
]
})
.where(
{ catalogNumber : “Z286004” },
{ modelNumber: “Z286004” }
)
.exec
In this particular case, here is how I would do it:
// Each element in the array is treated as 'or'
var possibleDeviceCategories = [
'cardiology valve bioprosthesis',
'nephrology haemodialysis catheter'
];
FdbDevice
.find({
deviceCategory: possibleDeviceCategories,
catalogNumber: 'Z286004',
modelNumber: 'Z286004'
})
.exec(cb);
Check out the docs for more informations about the Waterline's query language.
you can try something like that, into the find:
FdbDevice
.find({or:
[
{ deviceCategory: “cardiology valve bioprosthesis” },
{ deviceCategory: “nephrology haemodialysis catheter” }
]
})
.where(
{ catalogNumber : “Z286004” },
{ modelNumber: “Z286004” }
)

Can I use Sails native query with populate?

I am using the native method of sails-mongo to query a collection. I need to use native to access some of the Mongo geospatial query features.
I would like to use the sails populate syntax to include associated models.
Is there a way to do this?
Here is an example of my existing code:
Trip.native(function(err, collection) {
collection.find(
{
"locationTo": {
"$near": {
"$maxDistance": 80467.35439432222,
"$geometry": {
"type": "Point",
"coordinates": [-117.133655, 32.720519]
}
}
}
}
)
.toArray(function(err, trips) {
console.log("Trips nearby:", trips);
});
});
Here is my Trip model for reference.
var Trip = {
attributes: {
owner: {
model: 'User'
},
title: 'string',
addressFrom: 'string',
locationFrom: 'json', // geoJson
dateTimeDepart: 'datetime',
dateTimeArrive: 'datetime',
dateTimeReturn: 'datetime',
addressTo: 'string',
locationTo: 'json', // geoJson
driver: {
model: 'User'
},
status: {
type: 'string',
defaultsTo: 'PENDING'
}
}
}
Would be helpful if you share the Trip model as well. If the field you wish to populate has type "collection" (not "array"), you should be able to populate it just fine.
Update: Alright, I got your question wrong. There doesn't seem to be any way of populating directly after a native call. There's really not much you can do with a native call as far as Waterline functions are concerned. I would suggest either running another query(Waterline) after you've fetched locationTo or populating the fields yourself since you only need to populate two of them(and that too from the same model). I can't think of anything that would suffice with a single query.
Thanks, I ended up doing it in two queries for now.
First, I build an array of matching ID's via the native query.
var tripIdList = trips.map(function (trip) {
return trip._id
});
Second, I do a normal find query using the ID list. It's not a single query but works well. Thanks for the help
Trip.find(filter)
.where({id: tripIdList})
.populate('driver')
.exec(function (err, trips) {
console.log("Trips:", trips);
}

How do I use new Meteor.Collection.ObjectID() in my mongo queries with meteor?

I have a Collection that has documents with an array of nested objects.
Here is fixture code to populate the database:
if (Parents.find().count() == 0) {
var parentId = Parents.insert({
name: "Parent One"
});
Children.insert({
parent: parentId,
fields: [
{
_id: new Meteor.Collection.ObjectID(),
position: 3,
name: "three"
},
{
_id: new Meteor.Collection.ObjectID(),
position: 1,
name: "one"
},
{
_id: new Meteor.Collection.ObjectID(),
position: 2,
name: "two"
},
]
});
}
You might be asking yourself, why do I even need an ObjectID when I can just update based off of the names. This is a simplified example to a much more complex schema that I'm currently working on and the the nested object are going to be created dynamically, the ObjectID's are definitely going to be necessary to make this work.
Basically, I need a way to save those nested objects with a unique ID and be able to update the fields by their _id.
Here is my Method, and the call I'm making from the browser console:
Meteor.methods({
upChild: function( options ) {
console.log(new Meteor.Collection.ObjectID());
Children.update({_id: options._id, "fields._id": options.fieldId }, {$set: {"fields.$.position": options.position}}, function(error){
if(error) {
console.log(error);
} else {
console.log("success");
}
});
}
});
My call from the console:
Meteor.call('upChild', {
_id: "5NuiSNQdNcZwau92M",
fieldId: "9b93aa1ef3868d762b84d2f2",
position: 1
});
And here is a screenshot of the html where I'm rendering all of the data for the Parents and Children collections:
Just an observation, as I was looking how generate unique IDs client side for a similar reason. I found calling new Meteor.Collection.ObjectID() was returning a object in the form 'ObjectID("abc...")'. By assigning Meteor.Collection.ObjectID()._str to _id, I got string as 'abc...' instead, which is what I wanted.
I hope this helps, and I'd be curious to know if anyone has a better way of handling this?
Jason
Avoid using the _str because it can change in the future. Use this:
new Meteor.Collection.ObjectID().toHexString() or
new Meteor.Collection.ObjectID().valueOf()
You can also use the official random package:
Random.id()