I'm trying out Google Cloud's datastore, and have run into a scenario I can't figure out.
I've got two entities of kind searchterm, both with a searchterm property, one "pink chicken", and the other with "red duck".
I'm attempting to use the GQL select * from searchterm where searchterm contains "chicken"
to retrieve the entity that has the searchterm property of "pink chicken". However, it doesn't seem to allow me to do that.
I have to fully state select * from searchterm where searchterm contains "pink chicken" to get the relevant response.
Does contains in GQL not mean what it implies? Would it be possible for me to perform a GQL query that has a wildcard in it to match strings?
Yes, I checked, that searchterm property IS indexed.
Thanks! :D
Cloud Datastore does not support such kind of queries and CONTAINS or contains is just there as equal but it does search substrings. For such cases like yours use the Search API.
You can refer this quote here:
Notice that the operator = is another name for the IN and CONTAINS operators. For example, <value> = <property-name> is the same as <value> IN <property-name>, and <property-name> = <value> is the same as <property-name> CONTAINS <value>. Also <property-name> IS NULL is the same as <property-name> = NULL.
And about the fact that datastore does not support this kind of queries refer to this link:
Restrictions on queries
The nature of the index query mechanism imposes certain restrictions on what a query can do. Cloud Datastore queries do not support substring matches, case-insensitive matches, or so-called full-text search. The NOT, OR, and != operators are not natively supported, but some client libraries may add support on top of Cloud Datastore.
You can use '%' in GQL, so try filtering the query for '%chicken%' and should bring the results you're looking for.
Related
What's the updated and effient way to query sql like in firebase? I've search in forums and they say I should query all the documents then just do a javascript match function
Neither database provided by Firebase (Realtime Database and Firestore) have support for LIKE queries. This is not going to change any time soon, as these types of queries do not scale with the sort of indexes provided by these database.
You can do string prefix queries, which is similar to "WHERE field LIKE foo%", but that's all you get.
For Realtime Database, see:
Firebase matching substring
How to perform sql "LIKE" operation on firebase?
Firebase query - Find item with child that contains string
For Firestore, see:
Google Firestore: Query on substring of a property value (text search)
Firestore Comparison Operators - contains, does not contain, starts with
Is there a way to search sub string at Firestore?
Does Firestore support something like whereNotEqual?
For example, I need to get exact documents where key "xyz" is missing.
In Firebase realtime db, we could get it by calling *.equalTo(null).
Thanks.
Firestore does not support a direct equivalent of !=. The supported query operators are <, <=, ==, >, or >= so there's no "whereNotEqual".
You can test if a field exists at all, because all filters and order bys implicitly create a filter on whether or not a field exists. For example, in the Android SDK:
collection.orderBy("name")
would return only those rows that contain a "name" field.
As with explicit comparison there's no way to invert this query to return those rows where a value does not exist.
There are a few work-arounds. The most direct replacement is to explicitly store null then query collection.whereEqualTo("name", null). This is somewhat annoying though because if you don't populate this from the outset you have to backfill existing data once you want to do this. If you can't upgrade all your clients you'll need to deploy a function to keep this field populated.
Another possibility is to observe that usually missing fields indicate that a document is only partially assembled perhaps because it goes through some state machine or is a sort of union of two non-overlapping types. If you explicitly record the state or type as a discriminant you can query on that rather than field non-presence. This works really well when there are only two states/types but gets messy if there are many states.
Cloud Firestore now supports whereNotEqualTo in database queries.
Keep in mind if you have more than one field in your query you may have to create a composite index in Cloud Firestore.
According to Datastore Queries there is Operator.IN keyword, allowing to specify multiple query values in single request.
However, it looks absent in gcloud-java-datastore:0.2.2.
What's the workaround to minimize the round-trip time of multiple single requests?
Is there any limitation on how many parallel queries are allowed?
The IN operator is a client-side feature of the Python NDB Client Library, it is not a native Cloud Datastore feature.
Under the covers, the client library splits the query by the IN clause and issues a separate query for each of values. It will then merge all the results together client-side to give you the result.
Since it is a client-side feature, you'll not that other query features cannot really be used with it, such as paging/cursors.
Alternative
If you are issue a static list of values for the IN clause (e.g. 'NEW', 'OPEN', 'ASSIGNED'), consider creating a Boolean field that is set at write-time (e.g. 'is_active') that pre-calcs the total IN clause for the entity.
This will perform better and work in client libraries other than NDB.
In updated documentation on Datastore Queries Operator.IN is not present anymore.
According to docs, there is no difference between IN and = operator:
Comparators are either equivalence comparators: =, IN, CONTAINS, = NULL, HAS ANCESTOR, and HAS DESCENDANT, or inequality comparators: <, <=, >, >=, !=, NOT IN.
Notice that the operator = is another name for the IN and CONTAINS operators.
I am using DB Browser for SQLite. The documentation for SQLite's fts3 says "FTS is primarily designed to support Boolean full-text queries". I built a virtual table using fts4 and successfully executed a few WHERE ... MATCH queries. But the following attempts give errors:
SELECT id FROM histsearch WHERE id MATCH ("-1456" IN BOOLEAN MODE);
SELECT id FROM histsearch WHERE NOT EXIST id MATCH ("1457");
Is the problem in DB Browser or in SQLite? How else can I write this query so it will work?
SQLite's full text service (fts3) basically offers Boolean Mode by default, no search modifier needed. DB Browser uses fts's standard query syntax, so NOT is not supported. To exclude a term, do something like
SELECT * FROM indexed WHERE indexed MATCH 'sqlite -database';
Edit: however, you cannot only exclude search terms in fulltext search:
An FTS query may not consist entirely of terms or term-prefix queries with unary "-" operators attached to them.
You'll have to use NOT LIKE for that.
I am trying to perform queries using the OR operator as following:
MapReduceResult result = riakClient.
mapReduce("some_bucket", "Name:c1 OR c2").
addMapPhase(new NamedJSFunction("Riak.mapValuesJson"), true).
execute();
I only get the 1st object in the query (where name='c1').
If I change the order of the query (i.e. Name:c2 OR c1) again I get only the first object in query (where name='c2').
is the OR operator (and other query operators) supported in the java client?
I got this answer from Basho engeneer, Sean C.:
You either need to group the terms or qualify both of them. Without a field identifier, the search query assumes that the default field is being searched. You can determine how the query will be interpreted by using the 'search-cmd explain' command. Here's two alternate ways to express your query:
Name:c1 OR Name:c2
Name:(c1 OR c2)
both options worked for me!