Using GQL sort by the count of a ListProperty - sql-order-by

If I have an db.Model object such as:
class Foo(db.Model):
title = db.StringProperty()
bars = db.ListProperty(db.Key)
and I wanted to query the datastore for all of the Foo entities and sort that set by the Foo objects that have the most bars, how would I write the GQL?
I was hoping for something as simple as:
fooQuery = db.GqlQuery("SELECT * FROM Foo ORDER BY len(bars) DESC"
but that doesn't work...

If you need to do something like that, you'll have to include another IntegerProperty to store the length, and keep it in sync yourself. GQL does not support that query.

Related

How do I negate a query in Parse's API (Back4App)? Specifically, how do I get everything not in a relation?

Does anyone know if there's an easy way to negate a parse query? Something like this:
Parse.Query.not(query)
More specifically I want to do a relational query that gets everything except for the objects within the query. For example:
const relation = myParseObject.relation("myRelation");
const query = relation.query();
const negatedQuery = Parse.Query.not(query);
return await negatedQuery.find();
I know one solution would be to fetch the objects in the relation and then create a new query by looping through the objectIds using query.notEqualTo("objectId", fetchedObjectIds[i]), but this seems really circuitous...
Any help would be much appreciated!
doesNotMatchKeyInQuery is the solution as Davi Macedo pointed out in the comments.
For example, if I wanted to get all of the Comments that are not in an Article's relation, I would do the following:
const relationQuery = article.relation("comments").query();
const notInRelationQuery = new Parse.Query("Comment");
notInRelationQuery.doesNotMatchKeyInQuery("objectId", "objectId", relationQuery);
const notRelatedComments = await notInRelationQuery.find();
How I understand it is that the first argument is specifying the key in the objects that we are fetching. The second argument is specifying the key in the objects that are in the query that we're about to argue. And lastly we argue a query for the objects we don't want. So, it essentially finds the objects you don't want and then compares the values of the objects you do want to the values of the objects you don't want for the argued keys. It then returns all the objects you do want. I could probably write that more succinctly, but w/e.

How to serialize tuples in django rest framework? Or, is there any way to convert tuple into queryset?

My views.py contains a view like:
class RankViewSet(generics.mixins.CreateModelMixin,
generics.mixins.ListModelMixin,
viewsets.GenericViewSet):
def get_queryset(self):
with connection.cursor() as cursor:
query = "SELECT ... "
cursor.execute(query)
row = cursor.fetchall()
return row
Here, get_queryset(self) returns some tuples like following:
((name1, college1, semester1), (name2, college2, semester2), (name3, college3, semester3), ...)
All of the fields are from different models, so I have to fetch these data using raw sql. How can I serialize this tuple in django rest framework? Or Is there any way to convert tuple in queryset?
Only just seen this question but answer may still be useful...
Off the top of my head you have a few options:
serializers.ListField -as you basically have a list of lists, if the content is all the same type you can do child=serializers.ListField(child=serializers.CharField())
serializers.SerializerMethodField()..and call mySerialiser(many=True) with the set
name = serializers.SerializerMethodField()
def get_name(self, obj):
return obj[0]
Having said this unless you have a very specific reason to use a raw sql query, as you are using django you should take advantage of its ORM engine and then you can use rest_framework model serializer. If speed is an issue you can use .only() and .defer() with your queries.

retrieve data with Contains id

Raven DB gave me this message
Method not supported: Contains
for this code :
using (var d = DataLayer.RavenDB.d.OpenSession())
{
foos = d.Query<Foo>().Where(foo => ids.Contains(foo.Id)).Skip(i * 10).Take(10).ToList();
}
how can I retrieve my list foos ?
It looks like you are trying to query multiple documents by id. Querying by Id is not recommended in Raven. Load them instead. There is an overload that takes multiple Ids.
foos = session.Load<Foo>(ids);
If this was some other property rather than Id, you would use item.In(list) rather than list.Contains(item).
if you want to load the documents based on the list of ids, go the solution suggested by Matt, performance wise Load() is the best approach.
but if you still wants to get it using Query (using some where contiions) change the code like this
using (var d = DataLayer.RavenDB.d.OpenSession())
{
foos = d.Query<Foo>()
.Where(foo => foo.Id.In<string>(ids))
.Skip(i * 10)
.Take(10).ToList();
}

Grails many to many with 3 classes: sorting by the number of relationships

Let's say we have 3 domain classes: 2 classes related with each other through a 3rd class.
Ok, some code:
class A {
String subject
String description
static hasMany = [cs: C]
static transients = ['numberOfCs']
Long getNumberOfCs() {
return cs.size()
}
}
class B {
String title
}
class C {
A objectA
B objectB
static belongsTo = [a: A]
}
Pretty clear? I hope so. This work perfectly with my domain.
You can see the transient property numberOfCs, which is used to calculate the number of C instances related to my A object. And it works just fine.
The problem: listing all my A objects, I want to sort them by the number of relationships with C objects, but the transient property numberOfCs cannot be used for the scope.
How can I handle the situation? How can I tell GORM to sort the As list by numberOfCs as it would be a regular (non transient) field?
Thanks in advance.
I'm not sure that Grails' criteria do support this, as you need both to select the A object itself and aggregate by a child objects (C). That means grouping by all the A's fields, which is not done automatically.
If you only need some fields from A, you can group by them:
def instances = A.withCriteria {
projections {
groupProperty('subject')
count('cs', 'cCount')
}
order 'cCount'
}
otherwise you'll need to retrieve only ids and make a second query, like in this question.
Another way is to use derived properties like described here (not sure it will work though):
class A {
static mapping = {
numberOfCs formula: 'select count(*) from C where c.b_id = id'
}
}
I wouldn't consider your Problem GORM related but rather general Hibernate or even SQL related.
Take a look at the HQL Docu they are a lot of examples.
check the following HQL this pretty close what you are asking.
select mySortedAs from A mySortedAs left join mySortedAs.cs myCsOfA order by
count(myCsOfA)
I think I saw somewhere that you also can do something like this myCsOfA.length or myCsOfA.size

Use LINQ to select elements within a generic list and casting to their specific type

I have a base class, called NodeUpgrade, which have several child types. An example of a specific child class is FactoryUpgrade.
I have a list of NodeUpgrades, which can be a mix of different child types. How do I write a linq query to retrieve a type of NodeUpgrade and cast to that specific type?
My working query looks something like this:
var allFactories = (from Node n in assets.Nodes
from FactoryUpgrade u in n.NodeUpgrades
where u.ClassID == NodeUpgradeTypes.Factory
select u)
This, of course, doesn't work. Can I specify the final type of the output?
If you are sure that every type in a sequence is a given type, you can use the Cast<T>() extension method. If there can be multiple types in the list and you only want one of them, you can use OfType<T>() to filter the sequence.
List<Animal> animals = ...
// assumes all animals are cats
var cats = animals.Cast<Cat>();
// var cats = (from animal in animals where ... select animal).Cast<Cat>();
// or maybe animals can contain dogs, but you don't want them
var cats = animals.OfType<Cat>();
The difference is that Cast will throw an exception if an animal isn't a cat, whereas OfType will perform a type check before actually trying the conversion. I would favor Cast over OfType when you are confident of the uniform type. (Also note that these do not perform user-defined conversions. If you have defined an implicit or explicit conversion, those will not be supported by these methods.)
The resulting sequence in each case will be IEnumerable<Cat>, which you can do further query operations on (filters, groupings, projections, ToList(), etc.)
You can use the method OfType<>
var allFactories = (from Node n in assets.Nodes
from FactoryUpgrade in n.NodeUpgrades
where u.ClassID == NodeUpgradeTypes.Factory
select u).OfType<ChildType>();
As others have said, use the .OfType extension method to filter the types (assuming you have set the inheritance model and appropriate discriminators on your data source). This will translate in the database to include the appropriate Where clause on the discriminator (ClassID).
var allFactories = from n in assets.Nodes
from u in n.NodeUpgrades.OfType<FactoryUpgrade>()
select u;
You didn't specify here if you were using EF, LINQ to SQL, or just Linq to Objects in this case. Each has a different way of modeling the inheritance. If you need help with the modeling portion, let us know which OR/M you are using.

Resources