My database structure mainly consists of multiple primary keys per table, therefore multiple columns are required per join. I'm trying to use ColdFusion (11 to be specific) ORM collection property. It seems that a comma separated list of columns in the fkColumn attribute doesn't work, like it does for relationship properties. I have filed a bug with Adobe, but I'm wondering if anyone else has run into this and found workarounds. Or maybe I'm just doing it wrong..
Table Setup
Years Staff StaffSites Sites
=========== ============ ============ ===========
YearID (PK) StaffID (PK) YearID (PK) SiteID (PK)
YearName StaffName StaffID (PK) SiteName
SiteID (PK)
Staff ORM CFC
component persistent=true table='Staff' {
property name='id' column='StaffID' fieldType='id';
property name='year' column='YearID' fieldType='id';
property name='sites' elementColumn='SiteID' fieldType='collection' table='StaffSites' fkColumn='StaffID,YearID';
}
The Problem
There is an error when running the generated query: [Macromedia][SQLServer JDBC Driver][SQLServer]An expression of non-boolean type specified in a context where a condition is expected, near ','.
Taking a look at the generated query, it appears that the list of columns is not properly parsed for the where clause, but it somewhat understands that there are multiple columns in the select expression.
select
sites0_.StaffID,
YearID as StaffID1_2_0_,
sites0_.SiteID as SiteID4_0_
from
StaffSites sites0_
where
sites0_.StaffID,YearID=?
The Goal
For the ORM collection property to correctly support a multi-key "join". Why not use a relationship? I'd like to use ORM objects to then serialize as JSON for use in the REST services. The serialized JSON needs to contain the ID for the relationships, not the actual relationship data. For example, the JSON payload should be:
{
"id": 1234,
"year": 2015,
"sites": [1,2,3]
}
Instead of something like:
{
"id": 1234,
"year": 2015,
"sites": [
{"id": 1, "name": "Foo"},
{"id": 2, "name": "Bar"},
{"id": 3, "name": "Baz"},
]
}
For your DB structure, the simplest way to translate into ORM would be to use "StaffSites" as linktable for many-to-many relationships.
You should try CF11's Custom serializer http://blogs.coldfusion.com/post.cfm/language-enhancements-in-coldfusion-splendor-improved-json-serialization-2
Related
I have below document JSON (pasted partial JSON, actual JSON will be complex and embedded). The JSON has Code as ParitionKey, I am trying to build No SQL database documents by migrating my sql tables, and I will have Code, Type making Unique row, as you can see below Code = 4 is duplicated with different Type and id I just generated GUID (not sure on id field so generated GUID and assigned to it).
we only have two values for Type filed, it's either RI or NRI for entire data, and Code is duplicated like below sample data Code:4, but combination of Type & Code fields make it unique.
Example JSON:
{
"id" : "88725628-2a9a-4fc7-90ed-29c5ffbd45fa"
"Code": "4",
"Type": "RI",
"Description": "MAC/CHEESE ",
},
{
"id" : "88725628-9a3b-4fc7-90ed-29c5ffbd34sk"
"Code": "8",
"Type": "RI",
"Description": "Cereals",
},
{
"id" : "88725628-6d9f-4fc7-90ed-29c4ffbd87de"
"Code": "4",
"Type": "NRI",
"Description": "Christmas Deal",
}
In NoSQL cosmos document db, I couldn't use two columns as partition key, so I have only code as Partition key, but when I am trying to insert into Cosmos Db how do I check if not exists then only insert or else I would end up creating duplicate documents:
CreateItemAsync --> I need a way to check if the document already exists if not then create
I have below code to check and if not found create Item
try
{
// Read the item to see if it exists.
ItemResponse<Item> itemResponse = await this.container.ReadItemAsync<Item>(itm.Id, new PartitionKey(itm.Code));
}
catch (CosmosException ex) when (ex.StatusCode == HttpStatusCode.NotFound)
{
// Create an item in the container representing the Andersen family. Note we provide the value of the partition key for this item, which is "Andersen"
ItemResponse<Item> itemResponse = await this.container.CreateItemAsync<Item>(itm, new PartitionKey(itm.Code));
}
But from above code in ReadItemAsync parameters, how do I know id parameter as it is a GUID randomly generated on every insert, is there a better way to utilize id property before insert into Cosmos DB, so it can be utilized while ReadItemAsync ?
second parameter is paritionKey, If I give code as partition key, it wouldn't work as expected as Code can be duplicated with different "Type" values and it's valid, but Code & Type together makes it unique and we shouldn't allow another document to be inserted if code and type are same.
How do I do it in Cosmos db insert ? I have below questions:
id field --> can I generate GUID and save document or id filed has any purpose which can be utilized during reads ?
Is it ok to pick a partition key which can potentially have duplicates like Code field.
How do I check document exists before insert with above qualifiers as Code filed can be duplicated but only With Type it makes it unique ?
Any suggestions ?
If code and type make a unique row then you should use the value of type for id as well rather than generating a GUID because in Cosmos DB the combination of your partition key and id must be unique.
Then when you do an insert, if the data is already there it will throw an exception which you can catch. For reads, if you know the value for code and type, you can use these to perform a point read to get a single row of data, rather than using a query. This is the most efficient way to fetch data in Cosmos DB.
It is fine to have duplicates for partition key values. You only need to make sure that you have less than 20GB of data for each partition key value.
I have set a secondary index with only a partition key (without a sort key), but I found that actually I can insert multiple items with the same partition key.
If I issue a query using the partition key in the secondary index, I'll get all the items where the partition key is equal to the given partition key value.
I'm a beginner of DynamoDB, I want to know if set a secondary index with only a partition key, but insert multiple items with the same partition key is a good idea.
I'm using Amplify.js and have this GraphQL schema:
type UserMeta #model #key(fields: ["owner"]) #auth(rules: [
{ allow: owner, operations: [create, delete, update] },
{
allow: groups,
groups: ["Admins"],
operations: [update, delete]
}
]) {
familyName: String
givenName: String
facebookUrl: AWSURL
twitterUrl: AWSURL
description: String
careers: [Career] #connection(keyName: "byOwner", fields: ["owner"])
owner: String!
}
type Career #model #key(name: "byOwner", fields: ["owner"]) #auth(rules: [
{ allow: owner, operations: [create, delete, update] },
{
allow: groups,
groups: ["Admins"],
operations: [update, delete]
}
]) {
id: ID!
company: String
companyUrl: AWSURL
industry: String
occupation: String
owner: String!
}
as you can see, the Career table has a secondary index byOwner with a partition key associated with owner(no sort key). but I can query the careers of a UserMeta normally.
with a traditional RDBMS, the index column can not be the same, I don't know why this is possible in DynamoDB, is this a best practice in DynamoDB??
Should I set a sort key for the byOwner index? maybe the sort key can be the id column?
with a traditional RDBMS, the index column can not be the same, I
don't know why this is possible in DynamoDB, is this a best practice
in DynamoDB??
Every RDBMS I've worked with allows both both unique and non-unique indexes.
The only uniqueness available in DDB is for the table's primary key.
It's very common to have records with the same partition key. In the table, records with the same partition key must have a different sort key.
For indexes, duplicates are allowed and again, this is very common use case.
One difference between RDBMS and DynamoDB is the latter expects you to know your data access patterns and use that to inform what shape the data should take. So this question ...
Should I set a sort key for the byOwner index? maybe the sort key can be the id column?
... can only be answered by knowing how you plan to load the Career objects.
If you're going to use a GraphQL query that only ever loads one at a time, like ...
type Query {
career(owner: String!, id: Id!)
}
... then adding the ID as a sort key is well worth it. It would mean the GraphQL Resolver for a Career will always be able to retrieve exactly the right object each time.
But if you'll need queries that will get a list of Career objects ...
type Query {
careers(owner: String!, since: dateString)
}
... and by default you only want to retrieve something like the "most recently created careers", then you would be better served by creating another attribute tracking when the career was created -- say createdAt: String! -- and use that as the sort key. The Resolver would then receive the list of careers by that owner in a logical sequence, allowing it to only read the oldest (or newest) careers.
This answer has some related info on how to use GSI's and sort keys with AWS AppSync.
I have a container keeping some documents like:
{
"id": "deece304-XXXXXXX-88e8-fcfc0c750e97",
"log_VehicleId": 123,
"latitude": -000.000,
"longitude": 111.111,
"_ts": 1593825193
}
my partition key is "log_VehicleId" i need a Cosmos SQl that gives me newset record of each partition
something like
Select top 1 from container c where c.log_VehicleId IN (123,234,312,123,873)
order by c._ts DESC
would be fantastic to have LINQ equivalent of that too
so I will have newest record per "log_VehicleId"
thanks
According to the documentation:
You currently cannot use GROUP BY with an ORDER BY clause but this is planned
So this is not supported now.You can vote and track this feature at here.
We are experiencing an issue in when writing queries for Cosmos Document DB and we want to create a new document property and use it in an ORDER BY clause
If, for example, we had a set of documents like:
{
"Name": "Geoff",
"Company": "Acme"
},
{
"Name": "Bob",
"Company": "Bob Inc"
}
...and we write a query like SELECT * FROM c ORDER BY c.Name this works fine and returns both documents
However, if we were to add a new document with an additional property:
{
"Name": "Geoff",
"Company": "Acme"
},
{
"Name": "Bob",
"Company": "Bob Inc"
},
{
"Name": "Sarah",
"Company": "My Company Ltd",
"Title": "President"
}
...and we write a query like SELECT * FROM c ORDER BY c.Title it will only return the document for Sarah and excludes the 2 without a Title property.
This means that the ORDER BY clause is behaving like a filter rather than just a sort, which seems unexpected.
It seems that all document schemas are likely to add properties over time. Unless we go back and add these properties to all existing document records in the container then we can never use them in an ORDER BY clause without excluding records.
Does anyone have a solution to allow the ORDER BY to only effect the Sort order of the result set?
Currently, ORDER BY works off of indexed properties, and missing values are not included in the result of a query using ORDER BY.
As a workaround, you could do two queries and combine the results:
The current query you're doing, with ORDER BY, returning all documents containing the Title property, ordered
A second query, returning all documents that don't have Title defined.
The second query would look something like:
SELECT * FROM c
WHERE NOT IS_DEFINED(c.Title)
Also note that, according to this note within the EF Core repo issue list, behavior is a bit different when using compound indexes (where documents with missing properties are returned).
Working on a Java application that uses Spring Data Couchbase 2.2.0.RELEASE...
Starting with a list of JSON objects that represent Book objects:
[
{id: 123, title: "Abc", category: "A"},
{id: 456, title: "Efg", category: "B"},
{id: 789, title: "Abc", category: "A"}
]
The array of Book objects are inserted into Couchbase. Later, the application would like get a list of distinct book titles back based on a category filter. Following some of the Spring documentation, I've arrived at this method name in the BookRepository interface:
List<Book> findDistinctTitleByCategory(String category);
However, the query that is created by Spring does not contain the Distinct clause for title. Here's is the final query that Spring sends to the CB cluster where bucket name here is default:
Executing N1QL query: {"statement":"SELECT META(`default`).id AS _ID, META(`default`).cas AS _CAS, `default`.* FROM `default` WHERE (`category` = \"A\")","scan_consistency":"not_bounded"}
Am I writing the method name wrong?
SDC currently does not support query derivation for distinct. I have created a ticket for enhancement here. In the meantime, you can work around by directly using #Query instead of n1ql.selectEntity, provide the select part.
If you are fetching only the title, SDC supports projections.
interface OnlyTitle {
String getTitle();
}
#Query(...)
OnlyTitle findDistinctTitleByCategory(String category);