Load joinedload results as a scalar list in SQLAlchemy ORM - sqlalchemy

How to load a joinedload in this example as a scalar list of ids:
session.query(tables.Roles).options(joinedload(tables.Roles.permissions).load_only(tables.Permissions.id)).filter(tables.Roles.id == id).first()
So that the result:
{
id:1,
name:"admin",
permissions: [1,3,6]
}
Insead of permissions being a set of objects:
{
id:1,
name:"admin",
permissions: [
{ id: 1 },
{ id: 3 },
{ id: 6 }
]
}

Related

Sequelize top level where with Op.or gives error

I am upleveling the includes to top level "where" so that I can OR it:
MODEL_A.findAll({
where: {
[Op.Or] : [
{
'$MODEL2_DETAIL.COLNAME$' : { [Op.eq]: 5 }
}, {
'$MODEL3_DETAIL.COLNAME$' : { [Op.eq]: 5 }
}
]
},
include: [{
model: MODEL2
as: 'MODEL2_DETAIL'
}, {
model: MODEL3,
as: 'MODEL3_DETAIL'
}
]
})
It gives error:
"Invalid value { '$MODEL2_DETAIL.COLNAME$': { [Symbol(eq)]: 5 } }"
If I put it without the Op.Or, it works
MODEL_A.findAll({
where: {
'$MODEL2_DETAIL.COLNAME$' : { [Op.eq]: 5 }
}
}...
Above works!
Any other suggestions how I can OR on multiple models?
https://sequelize.org/master/manual/eager-loading.html
Needs to be Op.or instead of Op.Or
Thank you #anatoly for noticing!

How to output object of an array in the root of the document in MongoDB using aggregation?

I have this document :
{"_id":"1", "elem":"ok",
"arrayOfObjects":[
{"type":"k","fieldx":"lol"},
{"type":"SndObject","fieldy":"foo"},
{"type":"Object1","fieldx":"bob"}
]
}
what is the aggregation to have this output:
{"_id":"1", "elem":"ok",
"Object1":[
{"type":"Object1","fieldx":"lol"},
{"type":"Object1","fieldx":"bob"}
],
"SndObject":[{"type":"SndObject","fieldy":"foo"}]
}
I found a way out, but it need me to know all the type i have:
{
"$addFields" : {
"Object1" : {
"$filter": {
"input": "$arrayOfObjects",
"as": "types",
"cond": {
"$and": [{ "$eq": [ "$$types.type", "Object1" ] }]
}
}
}
}
}
It would be best if i can loop over my arrayOfObjects and get the same result without pre knowledge of the type.
Might be there would be more easy option than this,
$unwind deconstruct arrayOfObjects array
$group by _id, type and elem, construct array of arrayOfObjects
$arrayToObject convert k and v from array to object
$group by _id and merge objects in root
db.collection.aggregate([
{ $unwind: "$arrayOfObjects" },
{
$group: {
_id: {
type: "$arrayOfObjects.type",
_id: "$_id"
},
elem: { $first: "$elem" },
arrayOfObjects: { $push: "$arrayOfObjects" }
}
},
{
$group: {
_id: "$_id._id",
elem: { $first: "$elem" },
arrayOfObjects: {
$mergeObjects: {
$arrayToObject: [[
{
k: "$_id.type",
v: "$arrayOfObjects"
}
]]
}
}
}
}
])
Playground

How to do where condition on include relation in Loopback

I want to get the result with include relation with where condition on include model.
return this.htcApi.find({
include: [
{
relation: 'nmos',
scope: {
include: 'countries',
},
},
],
where: { name:'Welcome', "nmos.name":'agile'}
});
This where is condition work for name of htc model not for noms module.
I want query like
Select htc.*, nmos.* FROM htc LEFT JOIN nmos ON nmos.id = htc.n_id where htc.name = 'abc' and nmos.name = 'abc';
How can add where condition on the "relation" table?
Simply you need to add where clause in 'scope' object which lies inside the 'include' object. So the code would be like :
return this.htcApi.find({
include: [
{
relation: 'nmos',
scope: {
include: 'countries',
where:{name:'agile'}
},
},
],
where: { name:'Welcome'}
});
In your query, you just need to add the property where within the scope property, like this:
return this.htcApi.find({
include: [
{
relation: 'nmos',
scope: {
include: 'countries',
where: {
and [
{ id: htc.n_id },
{ name: 'abc' },
],
},
},
},
],
where: { name: 'abc' }
});
This should return the htcApi objects named 'abc' with the related nmos objects that have the name 'abc' and the id 'n_id'.

mongodb $lookup has_many association from embedded document

I have a boards collection, a lists collection, and a cards collection. An array of lists is embedded in a board document. I am trying to get an output that looks like this:
{
_id: 1,
title: "a board",
lists: [
{
_id: 1,
title: "a list",
cards: [ { _id: 1, title: "a card", list_id: 1 }, { _id: 2, title: "another card", list_id: 1 } ]
},
...
]
}
I want to nest the cards in the list it belongs to. The card document has a list_id field. I tried this:
db.boards.aggregate([
{ '$match' => { _id: 1 } },
{ '$lookup' => {
from: "cards",
localField: "lists._id",
foreignField: "list_id",
as: "cards"
} },
])
But that resulted in:
{
_id: 1,
title: "a board",
lists: [ { _id: 1, title: "a list" } ],
cards: [ { _id: 1, title: "a card", list_id: 1 }, { _id: 2, title: "another card", list_id: 1 } ]
}
I know that I have to use $unwind to get the result I want, but I can't get it to work
You need one additional aggregation pipeline step to "merge" these two lists and you can achieve it by running $map with embedded $filter. It simply works as a "join" operation on two arrays:
{
$project: {
_id: 1,
title: 1,
lists: {
$map: {
input: "$lists",
as: "list",
in: {
$mergeObjects: [
"$$list",
{
cards: {
$filter: {
input: "$cards",
cond: { $eq: [ "$$this.list_id", "$$list._id" ] }
}
}
}
]
}
}
}
}
}
Mongo Playground

Grails JSON.registerObjectMarshaller

I need to change the format for a json response. I have a simple domain class, GeoCounter, mapped against a database table that looks like:
import grails.rest.Resource
import groovy.transform.ToString
#Resource(uri="/fieldvaluecounters", formats=['json'])
#ToString
class GeoCounter {
String id
int value
static transients = ['geoCountry']
static mapping = {
table 'geo_counter'
id name: 'geoCountry', column: 'geo_country', generator: 'assigned'
value column: 'numOfHits'
version false
}
static constraints = {
id(unique:true, blank: false)
}
void setGeoCountry(String geoCountry) {
id = geoCountry
}
String getGeoCountry() {
return id
}
}
and I need this returned:
`data = [{key: "twn", "value": 3 },
{key: "gbr", "value": 1 },
{key: "en", "value": 4}];`
My spring resources.groovy has:
omnitureMarshallerRegistrar(MarshallerRegistrar)
and the Marshaller has:
class MarshallerRegistrar {
#PostConstruct
void registerMarshallers() {
println "Registering customer marshallers"
JSON.registerObjectMarshaller(GeoCounter) { GeoCounter gc ->
return [
key: gc.getGeoCountry(),
value: gc.getValue()
]
}
}
}
but my method
/poc/api/fieldvaluecounters
still returns id & value instead of key, value. What am I missing?
[
{
id: "twn",
value: 3
},
{
id: "gbr",
value: 1
},
{
id: "en;q=0.8",
value: 1
},
{
id: "en;q=0.5",
value: 8
},
{
id: "jpn",
value: 36
},
{
id: "idn",
value: 1
},
{
id: "chn",
value: 2
},
{
id: "fra",
value: 11
},
{
id: "en-AU;q=0.8",
value: 1
},
{
id: "usa",
value: 2
}
]