How do I query in GQL using the entity key - google-app-engine

How do I write a query against the entity key using GQL in the Google App Engine Data Viewer ?
In the viewer, the first column (Id/Name) displays as name=_1, in the detail view it shows the key as
Decoded entity key: Programme: name=_1
Entity key: agtzcG9...................
This query does not work:
SELECT * FROM Programme where name = '_1'

You can use the entity's key to retrieve it:
SELECT * FROM Programme where __key__ = KEY('agtzcG9...................')
And, you should be able to query using the name similarly:
SELECT * FROM Programme where __key__ = KEY(Programme, '_1')
Note that this is not something that you would want to do in your AppEngine application; as Nick notes in his comment, it is a huge waste of time. Really, this example is only good to show you how to query by Key in the Admin console.

For numeric IDs, a form similar to the query-by-name works:
SELECT * from Programme where __key__ = KEY('Programme', 1234567)
I found this form especially useful in the Admin Console.

You don't need to query to get an entity by key at all - you can simply fetch the entity by its key. In Python, you can do this with MyModel.get_by_key_name('_1'). This is 3 to 5 times faster than Adam's suggestion of using a query.

When querying by key, you need to match the key exactly, including the parent and not just the ID or name. Of course, if the parent is null, as in the example above, the ID or Name and the type of entity is enough.
If you have the already encoded entity key, you can just use that like:
SELECT * FROM Programme where __key__ = KEY('agtzcG9...................')
For the simple example above,
SELECT * FROM Programme where __key__ = KEY('Programme', '_1')
will do, but if your key has a parent, like
Paren: id=123
Then the query would be
SELECT * FROM Programme where __key__ = KEY('Paren', 123, 'Programme', '_1')
If the parent itself has a parent, you need to add that too. For more details see the official GQL documentation.
There does not appear to be a way to select everything with the same ID or name regardless of parent.

Just a quick note on this: When I use any quotes around any of the args in KEY, the call fails (in the admin console I get the error popup).
For example, for type "mytype" with ID/Name 12345, this does NOT work:
SELECT * FROM mytype WHERE __key__ = KEY('mytype', '12345')
But this does:
SELECT * FROM mytype WHERE __key__ = KEY(mytype, 12345)

Related

How to Query range in Cassandra

I’m trying to query a integer on Cassandra table and get the error Only EQ and IN relation are supported on the partition key(unless you use the token()function) My table is setup Is below with the query I ran. Be aware I did not setup the table nor can I change it currently.
CREATE TABLE USERS(
accName text,
accContext text,
accNumber int,
accCount int,
accHost text,
PRIMARY KEY (accName,accContext,accNumber)
);
SELECT * FROM Users WHERE accName = 'tear' and accContext = 'db1'
and accNumber> 20200101 and accNumber<= 202002018;
It looks like your post-edit query:
SELECT * FROM Users
WHERE accName = 'tear' and accContext = 'db1'
and accNumber> 20200101 and accNumber<= 202002018;
...works just fine. If you specify accName (partition key) and accContext (1st clustering key), you absolutely can run a range query on an integer, assuming that it is the next clustering key. However, if you were to eliminate accContext from your query, this would fail because you're not giving Cassandra enough information to efficiently retrieve the desired data.
SELECT * FROM Users WHERE accNumber> 20200101 and accNumber<= 202002018;
So this was your query before being edited with a working solution. And of course, you saw the error stating that range queries on partition keys only work with the token function.
Why is that?
You've probably heard that Cassandra requires a "query based" approach to data modeling. This is because all data usually does not reside on a single node.
Cross-node queries are expensive. Forcing range queries on partition keys via token gives you the tools to limit your query to a node that is responsible for a specific token range. In your case, this works:
aaron#cqlsh:stackoverflow> SELECT token(accname),accname FROM Users
WHERE token(accname) <= -6425313154088713591
AND token(accname) > -7367992452875979971;
system.token(accname) | accname
-----------------------+---------
-6611994791738996364 | tear
(1 rows)
Deconstructing what I did here, by using the token function in my SELECT, I can see what the token of the string "tear" is. Next, I can query system.peers to see which node(s) are responsible for that token, as well as to get an idea of the exact token ranges the target nodes are responsible for.

Apply query criteria based on parameters

I need to run a query in a MS Access Database providing some parameters from a form. Imagine the next example:
I have a form which contains:
CheckBox1 and Text1
CheckBox2 and Text2
Button (to run query)
Now imagine a query with two fields: ID, NAME.
I want to filter ID by Text1 only when CheckBox1 is enabled. If not, I want the query not to filter ID in any way (as if the 'query' input was empty).
In the same way, I want to filter NAME by Text2 only when CheckBox2 is enabled. If not, I want the query not to filter NAME in any way (just like ID before).
I've tried so many things for a couple of days and have sniffed tons of internet pages and still don't come up with a solution.
You can use a SQL query such as the following:
select * from YourTable t
where
([Forms]![YourForm]![CheckBox1] = False or t.ID = [Forms]![YourForm]![Text1]) and
([Forms]![YourForm]![CheckBox2] = False or t.NAME = [Forms]![YourForm]![Text2])
(Change YourTable to the name of your table and YourForm to the name of your form; t is merely an alias so that you only have to change the table name in one place in the code).

Best rules to get data with Contain

In CakePHP 3 ORM has changed and I can't find the proper way to select needed data from the database.
In CakePHP 2, I use contain('User.name','User.id'), but In CakePHP 3 this code doesn't work.
So how can I select only id and name from User?
The code:
$query = $data->find()->contain(['Users'])->execute()->fetchAll('assoc');
// I want only user.id and user.name.
$articles = $this->Model->find()
->select(['fields_you_want_from_this_Model'])
->contain(['Assoc_Model' => function($q) {
return $q
->select(['fields_you_want_from_the_associated_model']);
}]);
U must take a look about this page: http://book.cakephp.org/3.0/en/orm/query-builder.html#passing-conditions-to-contain
In certain case you must use autoFields method.
Be carefull with contain when u select few fields in the callable, u always have to select the foreign key also:
When you limit the fields that are fetched from an association, you must ensure that the foreign key columns are selected. Failing to select foreign key fields will cause associated data to not be present in the final result.

Doctrine2 Mapping Problems on a Symfony2 Project

I have 2 entities Item and Itemimage. The relationship between Item to Itemimage is OneToMany Unidirectional with JoinColumn. I took help from doctrine documentation. The OneToMany unidirectional with JoinColumn is achieved with the ManyToMany Annotation:
/**
* #ManyToMany(targetEntity="Itemimage")
* #JoinTable(name="itemimage",
* joinColumns={#JoinColumn(name="item_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="image_id", referencedColumnName="itemid")}
* )
*/
Where:
image_id: itemid is a property in the Itemimage Entity
item_id: is the primary key property of the Item Entity
I made a property $images in Item Entity and gave it the above docblock. The problem is that when I tried updating the schema. I get a doctrine error: "The Table 'itemimage' already exists". I'm sure that is not the case. I have no idea what to do.
Please help me with this.
Thanks! I appreciate your help.
It is supposed to be:
/**
* #ManyToMany(targetEntity="Itemimage")
* #JoinTable(name="itemimage_map",
* joinColumns={#JoinColumn(name="item_id", referencedColumnName="id")},
* inverseJoinColumns={#JoinColumn(name="image_id", referencedColumnName="id")}
* )
*/
leading to the creation of a third table (itemimage_map) that will contain just the mapping of the other two tables. It is not an existing table you have to join there. That table will contain item_id and image_id which are the primary keys of tables you want to map.

Using INDEX in SQL Server

I need to create am index in SQL however it needs to display the records by entering only a part of the name. The index should be created to retrieve the student information using part of the student name (i.e. if the name if Johnanesburg; the user can input John)
I used the syntax below but it wont work
create index Student ON Student(SName)
SELECT * FROM Student WHERE StRegNo LIKE A%
go
I think your problem is here: A%
Try wrapping it in apostrophes.
SELECT *
FROM Student
WHERE StRegNo LIKE 'A%'
Also, you may want a GO statement after you create your index.
The index you are creating over SName will not provide as much benefit for the select statement you are running as one created over StRegNo. Assuming that StRegNo is the primary key on the Student table you could try:
CREATE CLUSTERED INDEX IX_Student on Student(StRegNo)
SELECT *
FROM Student
WHERE StRegNo LIKE 'A%'
However it appears that the SQL you have provided is at odds with your question. If you want to search based on student name then you might want the following instead.
CREATE NONCLUSTERED INDEX IX_Student on Student(SName)
SELECT *
FROM Student
WHERE SName LIKE 'A%'
Ardman got it right regarding your query %A => '%A'. Now as for the index, that's another story that no index can help you with at the time, neither can full text search. If you want to look for names starting with #A (i.e. John%), an ordered index could help but otherwise (i.e. %bur%), you will go for a full table scan !

Resources