wildcard in prisma full text search with postgresql - database

So I want to implement search feature to my web. In mysql we have * wildcard for 0 or more character match. But it seems we don't have any for postgress sql, I already checked the prisma documentation but I found nothing. I also tried &> and &< but it doesnt work.
Here's my code.
import { PrismaClient } from "#prisma/client"
export default async function handler(req, res) {
const prisma = new PrismaClient()
var searchWords = req.query.search.split(" ")
searchWords = searchWords.map(word => {
// return `wildcard${word}wildcard`
return `${word}`
})
const query = searchWords.join(" | ")
console.log(query)
const data = await prisma.diary.findMany(
{
where: {
body: {
search: query
}, title: {
search: query
}
},
orderBy: {
timecreated: 'desc'
},
take: 10
}
)
data.map(x => {
x.timecreated = x.timecreated.toString()
x.lastedited = x.lastedited.toString()
return x
})
await prisma.$disconnect()
res.status(200).json(data)
}

Related

How can i get the name of images and use the images

In product page, I want to get all images path that are in a specific folder and send those to client side, so I can use them in client side by passing the paths to Image component of next js. I tried this when I was developing my app via running npm run dev and it was successful. Then I pushed the changes to my GitHub repository and vercel built my app again. Now, when I go to the product page, I get an error from the server. I tried some ways to fix this problem, but I couldn't fix that. For example, I tried changing my entered path in readdir, but the problem didn't fix. Here are my codes:
const getPagePhotosAndReview = async (productName) => {
const root = process.cwd();
let notFound = false;
const allDatas = await fs
.readdir(root + `/public/about-${productName}`, { encoding: "utf8" })
.then((files) => {
const allDatas = { pageImages: [], review: null };
files.forEach((value) => {
const image = value.split(".")[0];
const imageInfos = {
src: `/about-${productName}/${value}`,
alt: productName,
};
if (Number(image)) {
allDatas.pageImages.push(imageInfos);
}
});
return allDatas;
})
.catch((reason) => (notFound = true));
if (notFound) return 404;
await fs
.readFile(root + `/public/about-${productName}/review.txt`, {
encoding: "utf-8",
})
.then((value) => {
allDatas.review = value;
})
.catch((reason) => {
allDatas.review = null;
});
return allDatas;
};
export async function getServerSideProps(context) {
if (context.params.product.length > 3) {
return { notFound: true };
}
if (context.params.product.length < 3) {
const filters = {
kinds: originKinds[context.params.product[0]] || " ",
};
if (context.params.product[1]) filters.brands = context.params.product[1];
const products = getFilteredProducts(filters, true);
if (products.datas.length === 0) {
return {
notFound: true,
};
}
return {
props: {
products: { ...products },
},
};
}
if (context.params.product.length === 3) {
const filters = {
path: context.resolvedUrl,
};
const product = getFilteredProducts(filters, false);
if (product.length === 0) {
return {
notFound: true,
};
}
const splitedPath = product[0].path.split("/");
const pagePhotosAndReview = await getPagePhotosAndReview(
splitedPath[splitedPath.length - 1]
);
if (pagePhotosAndReview === 404) return { notFound: true };
product[0] = {
...product[0],
...pagePhotosAndReview,
};
product[0].addressArray = [
textOfPaths[context.params.product[0]],
textOfPaths[context.params.product[1]],
];
return {
props: {
product: product[0],
},
};
}
}
This is the base code and I tried some ways but couldn't fix the problem. So to fix this problem, I want to ask: how can I get the name of all images in a specific directory and then use those images in client side? And errors that I get: if I go to a page directly and without going to the home of the website, I get internal server error with code of 500 and when I go to a page of my website, and then I go to my product page, I get
Application error: a client-side exception has occurred (see the browser console for more information).
And I should say that I know I should remove public from paths when I want to load an image from public folder. I did it but I still get error.

ElasticSearch | Delete function not working since update 8.0

In our React project, we use the npm package "#elastic/elasticsearch".
Since 8.0 migration, delete function is not working. We implement it this way:
// 1) Declaration of client instance
import { Client } from '#elastic/elasticsearch';
import Config from 'src/config';
const client = new Client(Config.get('/authentication/elastic'));
export default client;
// 2) Use delete fonction
public async delete(id: string): Promise<any> {
try {
return await this.client.delete({
index: this.indexName,
id: id,
});
} catch (e) {
return null;
}
}
The promise does not return an error, it sends this:
{
_index: 'visitor_0',
_id: 'RN-PdzFW-Yfr0ahMp',
_version: 3,
result: 'deleted',
_shards: { total: 2, successful: 1, failed: 0 },
_seq_no: 396,
_primary_term: 22
}
Problem, it does not delete the object. It updates it with empty content.
I try do delete manually on elastic dashboard, it works correctly.
I try do a small script by entering the id by hand, it also works.
// my small script
'use strict';
require('dotenv').config();
const util = require('util');
const elastic = require('./services/elastic/client').default;
const debug = o => console.log(util.inspect(o, false, null, true));
(async () => {
debug('Starting...');
const id = 'ChmG-wAL-YpjZAdGp';
try {
const result = await elastic.delete({ index: 'visitor', id });
debug(result);
} catch (e) {
debug(e);
}
})();
Do any of you have any idea where my problem could come from?

Apollo Client delete Item from cache

Hy I'm using the Apollo Client with React. I query the posts with many different variables. So I have one post in different "caches". Now I want to delete a post. So I need to delete this specific post from all "caches".
const client = new ApolloClient({
link: errorLink.concat(authLink.concat(httpLink)),
cache: new InMemoryCache()
});
Postquery:
export const POSTS = gql`
query posts(
$after: String
$orderBy: PostOrderByInput
$tags: JSONObject
$search: String
$orderByTime: Int
) {
posts(
after: $after
orderBy: $orderBy
tags: $tags
search: $search
orderByTime: $orderByTime
) {
id
title
...
}
}
`;
I tried it with the cache.modify(), which is undefined in my mutation([https://www.apollographql.com/docs/react/caching/cache-interaction/#cachemodify][1])
const [deletePost] = useMutation(DELETE_POST, {
onError: (er) => {
console.log(er);
},
update(cache, data) {
console.log(cache.modify())//UNDEFINED!!!
cache.modify({
id: cache.identify(thread), //identify is UNDEFINED + what is thread
fields: {
posts(existingPosts = []) {
return existingPosts.filter(
postRef => idToRemove !== readField('id', postRef)
);
}
}
})
}
});
I also used the useApolloClient() with the same result.
THX for any help.
Instead of using cache.modify you can use cache.evict, which makes the code much shorter:
deletePost({
variables: { id },
update(cache) {
const normalizedId = cache.identify({ id, __typename: 'Post' });
cache.evict({ id: normalizedId });
cache.gc();
}
});
this option worked for me
const GET_TASKS = gql`
query tasks($listID: String!) {
tasks(listID: $listID) {
_id
title
sort
}
}
`;
const REMOVE_TASK = gql`
mutation removeTask($_id: String) {
removeTask(_id: $_id) {
_id
}
}
`;
const Tasks = () => {
const { loading, error, data } = useQuery(GET_TASKS, {
variables: { listID: '1' },
});
сonst [removeTask] = useMutation(REMOVE_TASK);
const handleRemoveItem = _id => {
removeTask({
variables: { _id },
update(cache) {
cache.modify({
fields: {
tasks(existingTaskRefs, { readField }) {
return existingTaskRefs.filter(
taskRef => _id !== readField('_id', taskRef),
);
},
},
});
},
});
};
return (...);
};
You can pass your updater to the useMutation or to the deletePost. It should be easier with deletePost since it probably knows what it tries to delete:
deletePost({
variables: { idToRemove },
update(cache) {
cache.modify({
fields: {
posts(existingPosts = []) {
return existingPosts.filter(
postRef => idToRemove !== readField('id', postRef)
);
},
},
});
},
});
You should change variables to match your mutation. This should work since posts is at top level of your query. With deeper fields you'll need a way to get the id of the parent object. readQuery or a chain of readField from the top might help you with that.

graphql: how to handle prev page, next page, last page and first page properly?

For frontend I am using React + Relay. I have some connection at the backend that could be queried like:
query Query {
node(id: 123456) {
teams(first: 10) {
node {
id
name
}
page_info {
start_cursor
end_cursor
}
}
}
}
So for the traditional approach, I can use skip PAGE_SIZE * curr limit PAGE_SIZE to query for next page, prev page and first page and last page (In fact I can query for random page)
But how should I implement the frontend to make these requests elegantly?
#Junchao, what Vincent said is correct. Also, you must have a re-fetch query and send refetchVariables with your first value updated. I will try to provide you an example:
export default createRefetchContainer(
TeamsComponent,
{
query: graphql`
fragment TeamsComponent_query on Query
#argumentDefinitions(
first: { type: Int }
last: { type: Int }
before: { type: String }
after: { type: String }
) {
teams(
id: { type: "ID!" }
first: { type: Int }
last: { type: Int }
before: { type: String }
after: { type: String }
) #connection(key: "TeamsComponent_teams", filters: []) {
count
pageInfo {
endCursor
hasNextPage
}
edges {
node {
id
name
}
}
}
}
`,
},
graphql`
query TeamsComponent(
$after: String
$before: String
$first: Int
$last: Int
) {
...TeamsComponent_query
#arguments(
first: $first
last: $last
after: $after
before: $before
)
}
`,
);
I tried to build an example based on your code. This is basically the idea. The bottom query is the re-fetch one. Alongside with that, you must trigger this re-fetch somehow by calling this.props.relay.refetch passing your renderVaribles. Take a deep looker into the docs about this.
Hope is helps :)
UPDATE:
Just to add something, you could have a handleLoadMore function with something like this:
handleLoadMore = () => {
const { relay, connection } = this.props;
const { isFetching } = this.state;
if (!connection) return;
const { edges, pageInfo } = connection;
if (!pageInfo.hasNextPage) return;
const total = edges.length + TOTAL_REFETCH_ITEMS;
const fragmentRenderVariables = this.getRenderVariables() || {};
const renderVariables = { first: total, ...fragmentRenderVariables };
if (isFetching) {
// do not loadMore if it is still loading more or searching
return;
}
this.setState({
isFetching: true,
});
const refetchVariables = fragmentVariables => ({
first: TOTAL_REFETCH_ITEMS,
after: pageInfo.endCursor,
});
relay.refetch(
refetchVariables,
null,
() => {
this.setState({ isFetching: false });
},
{
force: false,
},
);
};
UPDATE 2:
For going backwards, you could have something like:
loadPageBackwardsVars = () => {
const { connection, quantityPerPage } = this.props;
const { quantity } = getFormatedQuery(location);
const { endCursorOffset, startCursorOffset } = connection;
const firstItem = connection.edges.slice(startCursorOffset, endCursorOffset)[0].cursor;
const refetchVariables = fragmentVariables => ({
...fragmentVariables,
...this.getFragmentVariables(),
last: parseInt(quantity || quantityPerPage, 10) || 10,
first: null,
before: firstItem,
});
return refetchVariables;
};

store.getRootField(...) returns null

I call an api to add a new request:
import { commitMutation, graphql } from "react-relay";
import { REQUEST_STATUS_NEW } from "../../../constants";
const mutation = graphql`
mutation CreateRequestMutation($input: CreateRequestInput!) {
createRequest(input: $input) {
request {
id
tid
title
description
price
commission
value
expirationDate
createdAt
completionDate
multipleResponders
draft
status
requestProposals
type {
id
name
}
industry {
id
name
}
applications {
id
}
myApplication {
id
}
}
}
}
`;
let tempId = 0;
function sharedUpdater(store, request) {
const root = store.getRoot();
const newRequests = root
.getLinkedRecords("requests", { own: true })
.filter(r => r);
if (!newRequests.find(m => m.getValue("id") === request.getValue("id"))) {
newRequests.push(request);
}
root.setLinkedRecords(newRequests, "requests", { own: true });
}
export const commit = (environment, input) => {
tempId += 1;
return commitMutation(environment, {
mutation,
variables: { input },
updater: store => {
const payload = store.getRootField("createRequest");
console.log('payload: ', payload)
const request = payload.getLinkedRecord("request");
sharedUpdater(store, request);
}
});
};
But each time I call it, store.getRootField return me null. I cant really understand where is the problem where I can investigate further. Any help appreciated. Seems like server doesnt have any issues at their side. How can I debug this?

Resources