Return only entities which have a list field empty in Objectify - objectify

Is it possible to filter entities in objectify, by only returning entities which have a specific list field empty?
For example, if I have a Client entity, which has an attribute "address", which is of kind List, how can I return only the clients that have no address associated at all?
Is there some sort of "is null" or "is empty" filter? Something like:
ofy().load().type(Client.class).filter("address", null).list();
or
ofy().load().type(Client.class).filter("address is", null).list();
Many thanks.

List properties are represented by the absence of data in the datastore; there's no way to store or index "an empty list".
Your best bet is to create a synthetic indexed property like 'addressless' and populate it in an #OnSave method:
class Client {
...
#Index(IfTrue.class) boolean addressless;
#OnSave void updateAddressless() {
this.addressless = address.isEmpty();
}
}
You can now filter by this. The property doesn't have to have getter/setters so it can be completely hidden from the rest of your application (other than as a filter criteria).
This strategy is often handy for dealing with situations that are hard to query for.

You cannot have an objectify filter with null as its value. How about changing the null list to an empty one?

Related

Get request data (GET) in a Symfony (5) formType without using data_class

I'm building a formType to filter products on a collection page. You can set multiple select boxes which makes other auto filled or unnecessary. I want to be able to manipulate the formType based on the data like when using a data_class object. I'm not using data_class because the search isn't a persisted object which is saved to the database. I'm using a GET form.
For example 2 select boxes:
category
productType
When setting a category makes some of the productTypes unnecessary. So i want to not show it.
To do so in the formType I need the data of the request (GET) but I can't find a way to do so.
To retrieve data from the form, you can use $form->getData().
As you're in a GET context, I suspect you can take advantage from FormEvents (take a closer look to POST_SET_DATA event) and get rid of values you don't need.
One other thing I would like to point out, is that you still can use some kind of object that's not persisted to DB, like DTO or whatever.
Forms and entities are not related anyhow, neither in the usage nor in the intentions.

Firestore: How to query data from a map of an array

Here is the schema for test db:
I want to write a query that can get all the documents where contacts have id=1 in any of the array index.
I have checked array_contains operator for firestore but the thing is my array have map which then have field id.
Thanks
You currently can't build a query that looks for an object field within an array. The only things you can find in an array are the entire contents of an array element, not a part of an element.
With NoSQL type databases, the usual practice is to structure you data in a way that suits your queries. So, in your case, you're going to have to structure your data to let you find documents where an array item contains a certain string. So, you could create another array that contains just the strings you want to query for. You will have make sure to keep these arrays up to date.
You could also reconsider the use of an array here. Arrays are good for positional data, but unless these contacts need to be stored in a certain order, you might want to instead store an object whose keys are the id, and whose field data also contains the id and name.
As Doug said, you can't query it,
but, if you could structure your data to something that looks like this
Store your data as a map
Use id as key and name as value
Now you can write a query that can get all the documents where contacts have id=1
db.collection("test").where("contacts.1", ">=", "").get()
If you have an array of maps or objects and want to get the docoments that contains this specific map/object like this ?
array_of_maps.png
you can use
queryForCategory(categName: string, categAlias: string): Observable[] {
firestore.collection('<Collection name>', ref =>
ref.where('categories',
"array-contains", {
"alias": categAlias,
"title": categName
}
One soulions is as #Doug said, to add array with the data you need to query, and keep it uptodate.
Another solution is to make contacts as sub collection of the document, an then you could make queries of the contacts and get its parrent.
final Query contacts = db.collectionGroup("contacts").whereEqualTo("id", 1);
for (DocumentSnapshot document : querySnapshot.get().getDocuments()) {
System.out.println(document.getId());
System.out.println(document.getString("parent_id"));
}
If you don't want to add parent as another field, you can get it from parent reference, check this answer https://stackoverflow.com/a/56223319/1278463
snapshot.getRef().getParent().getParent().collection("people")
https://firebase.google.com/docs/firestore/query-data/queries#collection-group-query

How to query google-cloud-datastore to find records that dont have a specific property

I want to query cloud datastore and find all records that dont have a property 'foo'
I was looking at the docs, but didnt find anything there.
Any pointers for such query would be appreciated.
You cannot do that with a query. You will have to read all records and check if the property exists in each of those entities and do what's needed.
The documentation states that -
Entities lacking a property named in the query are ignored
Entities of the same kind need not have the same properties. To be
eligible as a query result, an entity must possess a value (possibly
null) for every property named in the query's filters and sort orders.
If not, the entity is omitted from the indexes used to execute the
query and consequently will not be included in the query's results.
Note: It is not possible to query for entities that are specifically
lacking a given property. One alternative is to add the property with
a null value, then filter for entities with null as the value of that
property.

How to find index for a field (if any)

I have some indexes in portal_catalog, for various types.
Given a portal_type and a fieldname, how can I find out the name of the index (if any) for that field?
Some relevant pointers to documentation about zcatalog might help me too!
Thanks..
There is no easy one-on-one way to determine this. In Plone 4, there are basically three different ways that an index in the catalog can obtain the information from your content type.
Index configuration
First and foremost, indexes can optionally be configured with the name(s) of the attributes or methods to index on a given object. Indexes generally have a getIndexSourceNames method that'll tell you what items they'll index.
Usually this is the same as the index id, but this is not a given. Generally, if your field accessor is listed in the result of getIndexSourceNames then that index will be indexing that field for a given type:
from Products.CMFCore.utils import getToolByName
catalog = getToolByName(context, 'portal_catalog')
for index in catalog.index_objects():
if field.accessor in index.getIndexSourceNames():
print 'Index %s indexes %s' % (index.getId(), field.getName()'
In the above examples, I assumed you already have a hold of your field object in the variable field, with an actual instance of your type in the variable context.
Custom indexing adapters
When an object is indexed, the catalog also constructs a wrapper around the object and will look up indexing adapters for your object. These adapters are registered both for the indexed name (so the name listed in getIndexSourceNames) and an interface or class. If your content class implements that interface or has an indexing adapter directly registered for it's class or a base class, the indexing adapter can be brought into play.
Indexing adapters are arbitrary snippets of code, and thus could call any field on your content object to produce their results. There is no programmatic way for you to determine if a given field on your content type will be used, or if any fields will be used at all.
The CMFPlone.CatalogTool module lists several examples of indexing adapters, these are all registered for Interface, meaning all objects:
allowedRolesAndUsers collects security information about your object.
getObjPositionInParent determines the position of the current object in it's container. Thus, this indexer does not need any information from the object itself to determine it's value.
sortable_title takes your content Title value and generates a value suitable for sorting catalog search results with. It normalizes the value, lowercases it, and prefixes numbers with leading zeros to make sorting on numbered titles easier.
Direct method access
Fields are basically generated methods on your content object. But your content class can also implement methods on it's class. The same remarks as for custom indexing adapters apply here; these are arbitrary Python code so they could be using your content type fields, aggregating and mangling the information before passing it to the index.
The Archetypes BaseObject class (used in all Archetypes content types) defines the SearchableText method for example. This method takes all available fields with the searchable property set to True, tries to get each field value as plain text, and aggregates the results for the SearchableText index.
Conclusion
You can only make educated guesses about index contents as they relate to your fields. By introspecting index configuration, you won't see if there might be a custom indexer adapter masking your field (register a getField index adapter and it'll be used instead of directly calling getField). Custom indexers and class methods can still access your fields and pass on the information to a catalog index.
You just add an index for the method or attribute name that you want to use for the index value--there's nothing too tricky about it and it can potentially all be done TTW
If you need a bit more logic to grab the index, check out this stackoverflow question: Problem with plone.indexer and Dexterity

Asserting in NUnit that a collection is in the same order as an expected collection

I know how to check that a collection is ordered by some property:
Assert.That(actual, Is.Ordered.By("Foo"));
How can I assert that actual contains the elements (1,2,5,3,4) in this specific order (without writing a custom comparer).
Use
CollectionAssert.AreEqual(expectedIEnumerable, actualIEnumerable);
This checks that the items are equal and are in the same order.
I'm fairly sure that when you use Assert.That on a collection, you get collection assert functionality. So you can say stuff like
Assert.That(collection, Is.EqualTo(expectedCollection)); // Same order
or
Assert.That(collection, Is.EquivalentTo(expectedCollection)); // Same item count
as well as stuff like
Assert.That(collection, Has.Count.EqualTo(expectedSize));
The Has keyword opens you up to the stuff that was specific to collection asserts, and is really useful.

Resources