Related
I have the following interface in typescript:
export interface TypesenseAtlistedProEvent {
// IDs
id: string;
proId: string;
eventId: string;
startTime: Number;
stopTime: Number;
eventRate: Number;
remainingSlots: Number;
displayName: string;
photoURL: string;
indexOptions: string;
location: Number[];
}
and the following schema in Typesense:
{
"created_at": 1665530883,
"default_sorting_field": "location",
"fields": [
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "proId",
"optional": false,
"sort": false,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "eventId",
"optional": false,
"sort": false,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "startTime",
"optional": false,
"sort": true,
"type": "int64"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "stopTime",
"optional": false,
"sort": true,
"type": "int64"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "eventRate",
"optional": false,
"sort": true,
"type": "float"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "remainingSlots",
"optional": false,
"sort": true,
"type": "int32"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "displayName",
"optional": false,
"sort": false,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "photoURL",
"optional": false,
"sort": false,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "indexOptions",
"optional": false,
"sort": false,
"type": "string"
},
{
"facet": false,
"index": true,
"infix": false,
"locale": "",
"name": "location",
"optional": false,
"sort": true,
"type": "geopoint"
}
],
"name": "atlistedProEventIndex",
"num_documents": 0,
"symbols_to_index": [],
"token_separators": []
}
I look to upsert like the in the following:
const indexedDoc: TypesenseAtlistedProEvent = {
id: proId + eventId,
proId: proId,
eventId: eventId,
startTime: publicEvent.startTime.seconds,
stopTime: publicEvent.stopTime.seconds,
eventRate: publicEvent.eventRate,
remainingSlots: publicEvent.remainingSlots,
displayName: tpi.displayName,
photoURL: tpi.photoURL,
indexOptions: tpi.indexOptions,
location: [tpi.lat, tpi.lng],
};
return await typesenseClient
.collections("atlistedProEventIndex")
.documents()
.upsert(indexedDoc)
.then(() => {
return {success: true, exit: 0};
})
I am getting the following upon the query:
RequestMalformed: Request failed with HTTP code 400 | Server said: [json.exception.type_error.302] type must be number
I am passing it location as Number[], and trying to get that to update the geopoint in typesense. This is not working and thus it would be useful if:
I was able to locate the logs to go through. I would particularly like the logs given by the Typesense Cloud, and am feeling at a loss that I cannot find these.
I would like to pass in the geopoint as the right type in typescript. Right now, as you can see above, the location is of type Number[], which, from the examples I saw, assumed was right. It also may be the case that another field is off and I'm just missing it. Either way, I could really use some kind of server side logging coming from Typesense Cloud.
The error message is a little confusing, but the core of the issue is that the default_sorting_field can only be a numeric field, but it's currently set as a geopoint field (location), which is what that error is trying to convey.
So if you create a new collection without default_sorting_field, the error should not show up.
If you want to sort by geo location, you want to use the sort_by parameter: https://typesense.org/docs/0.23.1/api/geosearch.html#searching-within-a-radius
let searchParameters = {
'q' : '*',
'query_by' : 'title',
'filter_by' : 'location:(48.90615915923891, 2.3435897727061175, 5.1 km)',
'sort_by' : 'location(48.853, 2.344):asc'
}
client.collections('companies').documents().search(searchParameters)
I tried creating Stripe Custom account on test mode
Request
const createAccountTeacher = catchAsync(async (req, res) =>
{
const date = new Date();
let time = Math.floor(date.getTime() / 1000);
const email = req.body.email;
const country = req.body.country;
const createAccount = await stripe.accounts.create({
type: 'custom',
country: country,
business_type: 'individual',
tos_acceptance: {
date: time,
ip: '8.8.8.8',
},
business_profile: {
mcc: '5734',
url: 'http://google.com',
product_description: 'Good Product',
support_phone: '12345567',
product_description: 'Teaching Courses available',
support_phone: '+10000000000',
},
individual: {
first_name: 'ABC',
last_name: 'XYZ',
dob: {
day: 24,
month: 6,
year: 1992,
},
address: {
line1: '1996 W Highland Ave',
postal_code: 90002,
city: ' San Bernardino',
state: 'California',
},
email: email,
phone: '+1202-555-0454',
ssn_last_4: 9999,
id_number: 123459999,
},
external_account: {
object: 'bank_account',
country: 'US',
currency: 'usd',
account_number: '000123456789',
routing_number: 121000358,
},
capabilities: {
card_payments: { requested: true },
transfers: { requested: true },
},
});
if (createAccount) {
res.status(200).json({ data: createAccount });
}
});
Here as response
{
"data":
{
"details_submitted": true,
"type": "custom",
"metadata": {},
"id": "acct_1LNcOTD4Ev4rC234",
"object": "account",
"default_currency": "usd",
"capabilities": {
"transfers": "pending",
"card_payments": "pending"
},
"business_type": "individual",
"individual": {
"metadata": {},
"id": "person_1LNcOVD4Ev4rC234OQjvuHiP",
"object": "person",
"account": "acct_1LNcOTD4Ev4rC234",
"dob": {
"year": 1992,
"day": 24,
"month": 6
},
"requirements": {
"currently_due": [],
"past_due": [],
"eventually_due": [],
"pending_verification": [
"id_number",
"verification.document"
],
"errors": [],
"alternatives": []
},
"ssn_last_4_provided": true,
"phone": "+12025550454",
"relationship": {
"percent_ownership": null,
"title": null,
"owner": false,
"director": false,
"representative": true,
"executive": false
},
"future_requirements": {
"currently_due": [],
"past_due": [],
"eventually_due": [],
"pending_verification": [],
"errors": [],
"alternatives": []
},
"verification": {
"status": "pending",
"details": null,
"document": {
"details_code": null,
"front": null,
"details": null,
"back": null
},
"additional_document": {
"details_code": null,
"front": null,
"details": null,
"back": null
},
"details_code": null
},
"address": {
"line2": null,
"line1": "1996 W Highland Ave",
"state": "California",
"postal_code": "90002",
"city": " San Bernardino",
"country": "US"
},
"email": "lilypota#ema-sofia.eu",
"created": 1658321573,
"first_name": "ABC",
"id_number_provided": true,
"last_name": "XYZ"
},
"charges_enabled": false,
"settings": {
"dashboard": {
"display_name": "Google",
"timezone": "Etc/UTC"
},
"payouts": {
"debit_negative_balances": false,
"statement_descriptor": null,
"schedule": {
"interval": "daily",
"delay_days": 2
}
},
"card_issuing": {
"tos_acceptance": {
"ip": null,
"date": null
}
},
"bacs_debit_payments": {},
"payments": {
"statement_descriptor_kanji": null,
"statement_descriptor_kana": null,
"statement_descriptor": "GOOGLE.COM"
},
"sepa_debit_payments": {},
"card_payments": {
"statement_descriptor_prefix_kanji": null,
"statement_descriptor_prefix": null,
"statement_descriptor_prefix_kana": null,
"decline_on": {
"avs_failure": false,
"cvc_failure": false
}
},
"branding": {
"icon": null,
"secondary_color": null,
"logo": null,
"primary_color": null
}
},
"tos_acceptance": {
"ip": "8.8.8.8",
"user_agent": null,
"date": 1658321567
},
"requirements": {
"current_deadline": null,
"past_due": [],
"errors": [],
"disabled_reason": "requirements.pending_verification",
"pending_verification": [
"individual.id_number",
"individual.verification.document"
],
"currently_due": [],
"eventually_due": [],
"alternatives": []
},
"payouts_enabled": false,
"company": {
"tax_id_provided": false,
"phone": "+12025550454",
"owners_provided": true,
"verification": {
"document": {
"details_code": null,
"front": null,
"details": null,
"back": null
}
},
"address": {
"line2": null,
"line1": "1996 W Highland Ave",
"state": "California",
"postal_code": "90002",
"city": " San Bernardino",
"country": "US"
},
"executives_provided": true,
"directors_provided": true,
"name": null
},
"external_accounts": {
"has_more": false,
"total_count": 1,
"object": "list",
"url": "/v1/accounts/acct_1LNcOTD4Ev4rC234/external_accounts",
"data": [
{
"last4": "6789",
"account_holder_name": null,
"metadata": {},
"id": "ba_1LNcOUD4Ev4rC234XwzzfiqR",
"object": "bank_account",
"account_type": null,
"default_for_currency": true,
"account_holder_type": null,
"account": "acct_1LNcOTD4Ev4rC234",
"status": "new",
"available_payout_methods": [
"standard"
],
"bank_name": "BANK OF AMERICA, N.A.",
"currency": "usd",
"country": "US",
"routing_number": "121000358",
"fingerprint": "gqPBt6FUMZJkqc9q"
}
]
},
"future_requirements": {
"current_deadline": null,
"past_due": [],
"errors": [],
"disabled_reason": null,
"pending_verification": [],
"currently_due": [],
"eventually_due": [],
"alternatives": []
},
"country": "US",
"email": null,
"created": 1658321576,
"business_profile": {
"support_email": null,
"product_description": "Teaching Courses available",
"mcc": "5734",
"support_url": null,
"support_address": null,
"url": "http://google.com",
"support_phone": "+10000000000",
"name": null
}
}
}
Custom Account is created but the problem it is restricted because of identity document
I am trying to upload the document like this
const updateAccount = catchAsync(async (req, res) => {
// let imagepath = ${req.protocol}://${req.get('host')}/uploads/${req.file.filename};
if(req.file.path){
const file = await stripe.files.create({
purpose: 'identity_document',
file: {
data: fs.readFileSync(req.file.path),
name: req.file.filename,
type: 'application/octet-stream',
},
}, {
stripeAccount: 'acct_1LNcOTD4Ev4rC234',
});
if(file){
res.status(200).json({data:file})
}
}
})
Still the custom account is restricted.
I would appreciate little help.
When Implementing a search filter on a document withh populated documents and array of object, How can I enable the search filter to checkout the populated document or array for the searched word?
What I have only checks through the surface fields
async findAllFeedbacks(user: any, payload: FilterDto) {
if (payload.fields) {
const query = await this.distributionChannelsDocumentModel
.find({
[payload.fields]: {
$regex: `${payload.searchFilter}`,
$options: 'i'
},
})
.clone()
.where({ business: user.business })
.populate({
path: 'feedbackId',
// match: { 'feedbackId[payload.fields]': { $regex: `${payload.searchFilter}` } }
})
return { query, total: query.length }
} else {
const query = await this.distributionChannelsDocumentModel
.find()
.clone()
.where({ business: user.business })
.populate('feedbackId')
return { query, total: query.length }
}
}
Here is a response sample:
{
"query": [
{
"_id": "62a8645641b312b3a04a7233",
"feedbackId": {
"_id": "62a8642b41b312b3a04a722a",
"title": "Monthly Feedback test",
"questions": [
{
"title": "Rate Our Services test",
"subtitle": "Customer retention is our priority",
"type": "SMILEY"
}
],
"thankYouMessage": "Thanks for dropping a feedback",
"allowComment": true,
"allowEmail": true,
"allowFullName": false,
"allowAttachment": false,
"status": "Active",
"business": "62a83f5ab4b33de7307e9cb8",
"user": "62a83f59b4b33de7307e9cb6",
"createdAt": "2022-06-14T10:34:19.709Z",
"updatedAt": "2022-06-14T10:34:19.709Z",
"__v": 0
},
"user": "62a83f59b4b33de7307e9cb6",
"distributionChannelType": [
"email"
],
"meta": [
{
"sender": "string",
"subject": "string",
"positioning": "string",
"timing": "string",
"brandColor": "string"
}
],
"createdAt": "2022-06-14T10:35:02.092Z",
"updatedAt": "2022-06-14T10:35:02.092Z",
"__v": 0
},
{
"_id": "62b1c87510fae7f3a54b13b2",
"feedbackId": {
"_id": "62ac55d0b28630c3a8c9b940",
"title": "Yearly Feedback",
"questions": [
{
"title": "Rate Our Services",
"subtitle": "We love to hear from you! How is your Jumia food experience",
"type": "SMILEY"
}
],
"thankYouMessage": "Thanks for dropping a feedback",
"allowComment": true,
"allowEmail": true,
"allowFullName": false,
"allowAttachment": false,
"status": "Active",
"business": "62ac434542452ccb513f2241",
"user": "62ac434542452ccb513f223f",
"createdAt": "2022-06-17T10:22:08.863Z",
"updatedAt": "2022-06-17T10:22:08.863Z",
"__v": 0
},
"user": "62ac434542452ccb513f223f",
"distributionChannelType": [
"sms"
],
"meta": [
{
"position": "bottom",
"timing": "",
"brandColor": "#444"
}
],
"createdAt": "2022-06-21T13:32:37.895Z",
"updatedAt": "2022-06-21T13:32:37.895Z",
"__v": 0
}
],
"total": 2
}
In the above response, feedbackId is the populated document and questions is the array I would also want to search through when using the search filter
I'm new to Apollo Client and I'm trying to implement pagination for my product list. but I can't figure out why the existing parameter in the merge function always returns empty. my incoming parameter always updates with a new list each time I call fetchMore but the existing parameter always is empty That's why I can't merge the new list with the old one.
this is my client configuration:
/* eslint-disable #typescript-eslint/no-unsafe-return */
import { ApolloClient, InMemoryCache } from '#apollo/client'
import { AppEndpoints } from './const'
import { createLink } from './links'
const cache = new InMemoryCache({
typePolicies: {
ListProductSearchType: {
fields: {
items: {
keyArgs: false,
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
merge: (existing = [], incoming, { args }) => {
console.log('>>>args', args)
console.log('>>>existing', existing) // it's always empty
console.log('>>>incoming', incoming)
return [...existing, ...incoming]
},
},
},
},
},
})
const link = createLink(AppEndpoints.main)
const client = new ApolloClient({
cache,
// ssrMode: false,
link,
defaultOptions: {
mutate: {
errorPolicy: 'ignore',
},
query: {
fetchPolicy: 'cache-first',
},
},
})
export default client
this is my Graphql response:
{
"data": {
"productSearch": {
"listDto": {
"count": 10,
"items": [
{
"id": "1d37d4fe-79d9-440a-8869-2dca0327791b",
"code": "780133 Iceland Poppy",
"isMyfavorite": false,
"currency": "$",
"imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
"price": 429.29,
"compareAtPrice": 240.4,
"hasDiscount": true,
"visited": 27685,
"salesCount": 8148,
"createdDateTime": "2020-12-14T06:02:38.0469339+00:00",
"__typename": "ProductSearchDto"
},
{
"id": "ae15c925-75ef-4dde-aa07-0eeb1bbb75c8",
"code": "330338 Amaranth",
"isMyfavorite": false,
"currency": "$",
"imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
"price": 234.8,
"compareAtPrice": 211.32,
"hasDiscount": true,
"visited": 27660,
"salesCount": 6374,
"createdDateTime": "2020-12-05T15:04:37.4237772+00:00",
"__typename": "ProductSearchDto"
},
{
"id": "de23a1f8-5e79-4cf9-88f0-57518c42a82c",
"code": "690156 Snowflake",
"isMyfavorite": false,
"currency": "$",
"imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
"price": 110.11,
"compareAtPrice": 88.09,
"hasDiscount": true,
"visited": 27141,
"salesCount": 2278,
"createdDateTime": "2020-10-18T11:27:38.0467775+00:00",
"__typename": "ProductSearchDto"
},
{
"id": "fb298a9c-a3d7-4c0e-a96e-a552b98d340f",
"code": "375033 Peony",
"isMyfavorite": false,
"currency": "$",
"imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
"price": 337.68,
"compareAtPrice": 151.96,
"hasDiscount": true,
"visited": 27050,
"salesCount": 2483,
"createdDateTime": "2020-12-06T22:57:37.4236274+00:00",
"__typename": "ProductSearchDto"
},
{
"id": "d017638f-3062-49bf-99cc-0e06ba0882b9",
"code": "112093 Hyacinth, wild",
"isMyfavorite": false,
"currency": "$",
"imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
"price": 460.43,
"compareAtPrice": 326.91,
"hasDiscount": true,
"visited": 26843,
"salesCount": 530,
"createdDateTime": "2020-11-10T23:13:37.4235865+00:00",
"__typename": "ProductSearchDto"
},
{
"id": "682a3c04-a462-4cbd-be8f-8b65d024b73f",
"code": "914276 Iceland Poppy",
"isMyfavorite": false,
"currency": "$",
"imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
"price": 126.81,
"compareAtPrice": 100.18,
"hasDiscount": true,
"visited": 24055,
"salesCount": 6328,
"createdDateTime": "2021-01-05T11:05:38.0469862+00:00",
"__typename": "ProductSearchDto"
},
{
"id": "c48819e2-52f4-4324-9f11-616efbc1a744",
"code": "494847 Persian Candytuft",
"isMyfavorite": false,
"currency": "$",
"imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
"price": 405.95,
"compareAtPrice": 288.22,
"hasDiscount": true,
"visited": 23713,
"salesCount": 7474,
"createdDateTime": "2020-10-23T16:24:37.4236199+00:00",
"__typename": "ProductSearchDto"
},
{
"id": "7118ddd5-56cf-4e12-9665-accb5abf3f73",
"code": "682251 Violet",
"isMyfavorite": false,
"currency": "$",
"imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
"price": 184.09,
"compareAtPrice": 90.2,
"hasDiscount": true,
"visited": 23448,
"salesCount": 6196,
"createdDateTime": "2020-10-12T08:36:38.0469107+00:00",
"__typename": "ProductSearchDto"
},
{
"id": "9e69b51a-560e-4d5e-b956-d9438d996c61",
"code": "982376 Calendula",
"isMyfavorite": false,
"currency": "$",
"imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
"price": 62.25,
"compareAtPrice": 38.6,
"hasDiscount": true,
"visited": 23300,
"salesCount": 9072,
"createdDateTime": "2020-10-10T14:24:38.0463778+00:00",
"__typename": "ProductSearchDto"
},
{
"id": "623dde57-8daf-4637-b2d3-0ebbf166aad0",
"code": "138453 Manchineel",
"isMyfavorite": false,
"currency": "$",
"imageUrl": "https://devcdn.sonbol.nl/Product/flower.jpg",
"price": 121.92,
"compareAtPrice": 56.08,
"hasDiscount": true,
"visited": 22373,
"salesCount": 4735,
"createdDateTime": "2020-10-11T12:04:37.4235489+00:00",
"__typename": "ProductSearchDto"
}
],
"__typename": "ListProductSearchType"
},
"__typename": "GenericQueryResponseProductSearchType"
}
}
}
and this is my query:
export const GetProductSearchDocument = /*#__PURE__*/ gql`
query GetProductSearch($filter: GenericFilterRequestProductSearchReqInputType!) {
productSearch(filter: $filter) {
listDto {
count
items {
id
code
isMyfavorite
currency
imageUrl
price
compareAtPrice
hasDiscount
visited
salesCount
createdDateTime
}
}
}
}
i'm calling fetchMore like this:
const [pageIndex, setpageIndex] = useState(0)
const { productResults, loading, fetchMore } = useQueryProductSearchData()
// eslint-disable-next-line #typescript-eslint/unbound-method
const { formatMessage } = useIntl()
useEffect(() => {
if (pageIndex !== 0) {
fetchMore({
variables: {
filter: {
pageSize: 10,
pageIndex,
dto: {
filters: [],
},
},
},
})
}
}, [fetchMore, pageIndex])
const onViewMore = () => {
setpageIndex((pre: any) => pre + 1)
}
Try adding keyFields: [], like:
typePolicies: {
ListProductSearchType: {
keyFields: [],
fields: {
items: {
keyArgs: false,
// eslint-disable-next-line prefer-arrow/prefer-arrow-functions
merge: (existing = [], incoming, { args }) => {
console.log('>>>args', args)
console.log('>>>existing', existing) // it's always empty
console.log('>>>incoming', incoming)
return [...existing, ...incoming]
},
},
},
},
},
You should add read function to your field policy
const cache = new InMemoryCache({
typePolicies: {
ListProductSearchType: {
fields: {
items: {
//your code here
//then add this function
read(existing) {
return existing
},
},
},
},
},
})
I am using Mongoose to do a search for documents in a collection based on the criteria described below:
Document:
{
"_id": {
"$oid": "5a60621e20205641281f7c2f"
},
"key1": [
{
"available": true,
"required": true,
"name": "Name-1"
},
{
"available": true,
"required": true,
"name": "Name-2"
},
{
"available": true,
"required": true,
"name": "Name-3"
}
],
"__v": 0
}
I want to perform a search based on property key1. So basically what I want to do is pass the json object as search pattern below and get the result as the document above in return
[
{
"available": true,
"required": true,
"name": "Name-1"
},
{
"available": true,
"required": true,
"name": "Name-2"
},
{
"available": true,
"required": true,
"name": "Name-3"
}
]
Is there a way that I can achieve this?
You can check $eq in mongodb docs $eq.
const selector = [
{
"available": true,
"required": true,
"name": "Name-1"
},
{
"available": true,
"required": true,
"name": "Name-2"
},
{
"available": true,
"required": true,
"name": "Name-3"
}
];
Model.find({key1: {$eq: selector}}, (error, result) => {
if(!err) {
res.send(result);
}
});
Model is the collection you fetch from.