The actual patterns are not in English, so I created this simplified example to reproduce the problem: there are 3 levels of annotations (required for real application) and the 3rd level pattern does not work as expected.
The phrase to be recognized is:
a b c
What I expect:
1st level: "a" is annotated as A, "b" is annotated as "B"
2nd: if there are annotations A and B, annotate them all together as AB
3rd: if at least one annotation AB is present and there is word "c", annotate them all together as C
Patterns are shown below.
# 1.
{ pattern: (/a/), action: (Annotate($0, name, "A")) }
{ pattern: (/b/), action: (Annotate($0, name, "B")) }
# 2.
{ pattern: (([name:A]) ([name:B])), action: (Annotate($0, name, "AB")) }
# 3.
{ pattern: (([name:AB]+) /c/), action: (Annotate($0, name, "C")) }
#1 and #2 works and "a b" are annotated:
matched token: NamedEntitiesToken{word='a' name='AB' beginPosition=0 endPosition=1}
matched token: NamedEntitiesToken{word='b' name='AB' beginPosition=2 endPosition=3}
But the #3 pattern doesn't work even though one can see that we have 2 "AB" annotated tokens and it is exactly what is expected by #3 pattern.
Even more if I change #1 to be
{ pattern: (/a/), action: (Annotate($0, name, "AB")) }
{ pattern: (/b/), action: (Annotate($0, name, "AB")) }
pattern #3 works correctly:
matched token: NamedEntitiesToken{word='a' name='C' beginPosition=0 endPosition=1}
matched token: NamedEntitiesToken{word='b' name='C' beginPosition=2 endPosition=3}
matched token: NamedEntitiesToken{word='c' name='C' beginPosition=4 endPosition=5}
I can't find any difference between matched tokens when I use
# In this case #3 pattern works
{ pattern: (/a/), action: (Annotate($0, name, "AB")) }
{ pattern: (/b/), action: (Annotate($0, name, "AB")) }
or when I use
# In this case #3 pattern doesn't work
# 1.
{ pattern: (/a/), action: (Annotate($0, name, "A")) }
{ pattern: (/b/), action: (Annotate($0, name, "B")) }
# 2.
{ pattern: (([name:A]) ([name:B])), action: (Annotate($0, name, "AB")) }
In both cases I get the same annotation, but first scenario works and the second doesn't.
What am I doing wrong?
This works for me:
# these Java classes will be used by the rules
ner = { type: "CLASS", value: "edu.stanford.nlp.ling.CoreAnnotations$NamedEntityTagAnnotation" }
ENV.defaults["stage"] = 1
{ ruleType: "tokens", pattern: (/a/), action: Annotate($0, ner, "A") }
{ ruleType: "tokens", pattern: (/b/), action: Annotate($0, ner, "B") }
ENV.defaults["stage"] = 2
{ ruleType: "tokens", pattern: ([{ner: "A"}] [{ner: "B"}]), action: Annotate($0, ner, "AB") }
ENV.defaults["stage"] = 3
{ ruleType: "tokens", pattern: ([{ner: "AB"}]+ /c/), action: Annotate($0, ner, "ABC") }
There is a write up about TokensRegex here:
https://stanfordnlp.github.io/CoreNLP/tokensregex.html
Related
I have a graphql mutation defined as follows
type Mutation {
updateParts(
partId: String!
parts: PartRequest!
): UpdatePartsResponse!
}
input PartRequest {
name: String!
image: Strings!
boltTypes: [Bolts]!
}
input Bolts {
code: String!
metadata: String!
}
Mhy requirement was to update fields upon selection as following.
update all
mutation {
updateParts(
partId: "0x1223"
parts: {
name: "some"
image: "dark.png"
boltTypes: [
{ code: "A", metadata: "B" }
]
}
)
}
}
Update by selection: name only
mutation {
updateParts(
partId: "0x1223"
parts: {
name: "some"
}
)
}
}
Update by selection: parts only
mutation {
updateParts(
partId: "0x1223"
parts: {
boltTypes: [
{ code: "A", metadata: "B" }
]
}
)
}
}
How to construct a schema to achieve this ?
You have to make your arguments optional to achieve this. Try the following schema:
type Mutation {
updateParts(
partId: String!
parts: PartRequest!
): UpdatePartsResponse!
}
input PartRequest {
name: String
image: String
boltTypes: [Bolts!]
}
input Bolts {
code: String!
metadata: String!
}
Notice the PartRequest input object. The fields are nullable. That means you don't necessarily need to provide a value for those arguments. The ! means they are NON_NULL types, which means you have to provide a value for those always.
I have made the boltTypes field type to [Bolts!] which means the boltTypes field can be null, but the array cannot have null as an element.
Trying to pass nested variables to the GraphQL query but my server gets only top-level variables (shopId), everything else is null.
I tried:
#1
const CALCULATE_PACKAGE_PRICE = gql`
query CalculatePackagePrice(
$shopId: String!
$address1: String
$zip: String
$city: String
$countryCode: String
) {
calculatePackagePrice(
where: {
shopId: $shopId
destination: {
address1: $address1
zip: $zip
city: $city
countryCode: $countryCode
}
}
) {
name
price
userErrors {
field
message
}
}
}
`
const [calculatePackagePrice, { loading, data }] = useLazyQuery(
CALCULATE_PACKAGE_PRICE,
{
variables: {
shopId: shopId,
destination: {
address1: "Example 123",
zip: "123",
city: "Test",
countryCode: "US",
},
},
}
)
And #2:
export function CALCULATE_PACKAGE_PRICE({ shopId, destination }) {
return gql`
query CalculatePackagePrice {
calculatePackagePrice(
where: {
shopId: "${shopId}"
destination: {
address1: "${destination.address1}"
zip: "${destination.zip}
city: "${destination.city}"
countryCode: "${destination.countryCode}"
}
}
) {
name
price
userErrors {
field
message
}
}
}
`
}
const [calculatePackagePrice, { loading, data }] = useLazyQuery(
CALCULATE_PACKAGE_PRICE({
shopId: shopId,
destination: {
address1: "Example 123",
zip: "123",
city: "Test",
countryCode: "US",
},
})
)
It works just fine when I hardcoded variables content to the queries. What I'm doing wrong?
Here is a helpful snippet from graphql docs,
All declared variables must be either scalars, enums, or input object types. So if you want to pass a complex object into a field, you need to know what input type that matches on the server.
You're correctly passing in the variables as strings, but then trying (perhaps successfully, but I've never seen the syntax before) to create the object in the gql template string. Instead, create an input type for destination and where.
input WhereInput {
shopId: String!
destination: DestinationInput!
}
input DestinationInput {
address1: String!
zip: String!
city: String!
countryCode: String!
}
then change the query on the client (and update the server definition),
const CALCULATE_PACKAGE_PRICE = gql`
query CalculatePackagePrice($where: WhereInput!) {
calculatePackagePrice(where: $where) {
name
price
userErrors {
field
message
}
}
}
`
then pass the variables like,
const [calculatePackagePrice, { loading, data }] = useLazyQuery(
CALCULATE_PACKAGE_PRICE,
{
variables: {
where: {
shopId,
destination: {
address1: "Example 123",
zip: "123",
city: "Test",
countryCode: "US",
},
},
}
}
)
I have tables Principles and Tags. And there is a many-to-many relation between them (joined implicitly).
Without using prisma.raw, how can I run the following query?
SELECT p.id, p.title, p.description, p.createdAt, p.modifiedAt
FROM principle p
WHERE EXISTS (SELECT NULL
FROM _PrincipleToTag pt
WHERE pt.B IN (${tagIds.join(',')})
AND pt.A = p.id
GROUP BY pt.A
HAVING COUNT(DISTINCT pt.B) = ${tagIds.length})
How can I update this Prisma 2 query such that the principles returned are only principles that are associated with ALL of the provided tagIds?
export const principles = ({ tagIds }) => {
const payload = {
where: {
//TODO filter based on tagIds
},
}
return db.principle.findMany(payload)
}
The docs mention contains and in and every, but I can't find examples of what I'm trying to do.
I'm using RedwoodJs, Prisma 2, Apollo, GraphQL.
Update in response to comment: here is the SDL:
input CreatePrincipleInput {
title: String!
description: String
}
input CreatePrincipleWithTagsInput {
title: String!
description: String
tagIdsJson: String
}
input CreateTagInput {
title: String!
description: String
}
# A date string, such as 2007-12-03, compliant with the `full-date` format
# outlined in section 5.6 of the RFC 3339 profile of the ISO 8601 standard for
# representation of dates and times using the Gregorian calendar.
scalar Date
# A date-time string at UTC, such as 2007-12-03T10:15:30Z, compliant with the
# `date-time` format outlined in section 5.6 of the RFC 3339 profile of the ISO
# 8601 standard for representation of dates and times using the Gregorian calendar.
scalar DateTime
type Mutation {
createPrinciple(input: CreatePrincipleInput!): Principle
createPrincipleWithTags(input: CreatePrincipleWithTagsInput!): Principle
updatePrinciple(id: Int!, input: UpdatePrincipleInput!): Principle!
deletePrinciple(id: Int!): Principle!
createTag(input: CreateTagInput!): Tag!
updateTag(id: Int!, input: UpdateTagInput!): Tag!
deleteTag(id: Int!): Tag!
}
type Principle {
id: Int!
title: String!
description: String!
tags: [Tag]
createdAt: DateTime!
modifiedAt: DateTime!
}
type Query {
redwood: Redwood
principles(searchQuery: String, tagIds: [Int]): [Principle!]!
tags: [Tag!]!
tagsByLabel(searchTerm: String): [TagCount!]!
tag(id: Int!): Tag!
}
type Redwood {
version: String
}
type Tag {
id: Int!
title: String!
principles: [Principle]
description: String
createdAt: DateTime!
modifiedAt: DateTime!
}
type TagCount {
id: Int!
title: String!
count: Int!
principles: [Principle]
description: String
createdAt: DateTime!
modifiedAt: DateTime!
}
# A time string at UTC, such as 10:15:30Z, compliant with the `full-time` format
# outlined in section 5.6 of the RFC 3339profile of the ISO 8601 standard for
# representation of dates and times using the Gregorian calendar.
scalar Time
input UpdatePrincipleInput {
title: String
description: String
}
input UpdateTagInput {
title: String
description: String
}
It doesn't look like you are using prisma 2. Prisma 2 uses models (not types) and has arrays classified like Principles[] vs [Principles]. Maybe Redwood does the conversion(Never used it).
I created your model in Prisma 2 and used the following command to get a single principle that has the two tags associated with it. Keep in mind the IDs in there are from my test dataset. Hopefully, you can modify this to your code. If not, please create a sandbox/playground with minimal code for us to test.
export const principles = async ({ searchQuery, tagIds }) => {
const payload = {
where: {
OR: [
{ title: { contains: searchQuery } },
{ description: { contains: searchQuery } },
],
userId: userIdFromSession,
},
}
if (tagIds.length) {
const whereAnd = []
tagIds.forEach((tagId) => {
whereAnd.push({
tags: { some: { id: tagId } },
})
})
payload.where.AND = whereAnd
}
const result = await db.principle.findMany(payload)
return result
}
You could try something like this
export const principles = ({ searchQuery, tagIds }) => {
const payload = {
where: {
OR: [
{ title: { contains: searchQuery } },
{ description: { contains: searchQuery } },
],
// using the `in` operator like this
tagId: { in: tagIds },
userId: userIdFromSession,
},
}
console.log('db.principle.findMany(payload)', payload)
return db.principle.findMany(payload)
}
That should do the trick!
I had to resort to using AND for something similar - hope this helps!
const tagIds = [9,6];
where: {
// ...
AND: tagIds.map(tagId => ({
tags: {
some: {
id: {
equals: tagId,
},
},
},
})),
}
I have my GraphQL schema imported in FaunaDB and want to create a new question
type Choices {
key: String!
value: String!
question: Question
}
type Question {
title: String!
snippet: String
choices: [Choices!]! #relation
answer: String!
explanation: String!
}
type Query {
allQuestions: [Question!]!
}
To do so, I'm using axios and have my GraphQL mutation like that:
const CREATE_QUESTION = `
mutation($title: String!, $explanation: String!, $snippet: String, $answer: String!, $choices: [ChoicesInput]!) {
createQuestion(data: {
title: $title
explanation: $explanation,
snippet: $snippet,
answer: $answer,
choices: {
create: $choices
}
}) {
_id
explanation
answer
title
snippet
choices {
data {
key
value
}
}
}
}
`
Everything work except for the choices, I want to send an array of object but got the error:
Variable '$choices' expected value of type '[ChoicesInput]!' but got: "[ { key: 'A', value: '`0 1 2` and `0 1 2`' }, { key: 'B', value: '`0 1 2` and `3 3 3`' }, { key: 'C', value: '`3 3 3` and `0 1 2`' } ]". Reason: '[0]' Expected 'ChoicesInput', found not an object. (line 2, column 86): mutation($title: String!, $explanation: String!, $snippet: String, $answer: String!, $choices: [ChoicesInput]!) { ^
What should I make differently to be able to send my array of objects?
I would like to use regex with graphql query variable.
This does't return results:
export const query = graphql`
query(
$episodes: String!
) {
episodes: allMarkdownRemark(
filter: { fields: { slug: { regex: $episodes } } }
) {
edges {
node {
id
}
}
}
}
`;
However, this would work:
export const query = graphql`
query() {
episodes: allMarkdownRemark(
filter: { fields: { slug: { regex: "/episodes/travel/" } } }
) {
edges {
node {
id
}
}
}
}
`;
what's wrong?
Passing regex via query arguments should work, see the screenshot below. Make sure you're passing in the regex as string, not the actual regex. Also, you'll need to escape the middle slash:
context: {
- episodes: /episodes\/traveller/ <-- doesn't work
+ episodes: /episodes\/traveller/.toString() <-- works
or episodes: "/episodes\\/traveller/" <-- also works
}
Try it out in one of the graphiQL embed in this page