The generally accepted way to do bulk product importing in a Shopify App - graphql

I'm currently working on my first Shopify app and it requires bulk importing products. I'm looking around the web, and it appears there's no query to do bulk importing. It also looks like if I want to add the price to the items I import, I'll have to make a separate query from the one that creates the products in the first place.
I'm thinking the easier way would be to create a .csv but there's no query to upload a .csv either.
Has anyone tackled something like this before, and what's the usual way to go about it?

If not supported then standard graphql possibilities [possibly (not tested)] can (should be possible) be applied:
Aliases
You can make multiple queries/mutations within one request.
Guaranteed order of mutations on root level
Multiple (aliased) chains of mutations:
m1a: insert #1,
m1b: define #1 price,
m2a: insert #2,
m2b: define #2 price
...
Probably you can use arguments used for element creation (one mutation) to search item for following mutation (if id not required).
You can try/check this scenario in the playground.
Of course in this case you need to construct query dynamically (usually not advised) in the app. You will need dynamic aliases and input variable names.

Related

Laravel Lighthouse: how to delete records that match certain conditions (rather than deleting via primary key)

In Laravel Lighthouse GraphQL, I'd love to be able to delete records that match certain conditions rather than passing just an individual ID.
I get this error:
The #delete directive requires the field deletePostTag to only contain a single argument.
This functionality seems currently unsupported, but if I'm wrong and this is actually supported, please let me know, because this would be the most straightforward approach.
So then my second approach was to try to first run an #find query to retrieve the ID of the record that I want to delete (based on certain fields equaling certain values).
But https://lighthouse-php.com/4.16/api-reference/directives.html#find shows:
type Query {
userById(id: ID! #eq): User #find
}
and does not show how I could provide (instead of the primary key ID) 2 arguments: a foreign key ID, and a string.
How can I most simply accomplish my goal of deleting records that match certain conditions (rather than deleting via primary key)?
I'm not sure about the #delete functionality regarding multiple arguments, but from what you've posted that appears to be unsupported at the moment. Regarding your query, you should instead use something like #all in conjunction with #where which would allow you to filter the collection by as many vars/args as you'd like. If your argument list grows beyond 3 or so, I would take a look at Complex Where Conditions. They have worked very well for my team so far, and allow a lot of filtering flexibility.
Also take a look at the directive's docs stating:
You can also delete multiple models at once. Define a field that takes a list of IDs and returns a collection of the deleted models.
So if you return multiple models you'd like to delete from your query, you may use this approach to delete them all at once.

using an input field in FileMaker that is not related to any table?

I'm in need of entering a few data points in the UI of a FileMaker app that are used either for search or for computation, but that have no relation to any field in a database (and don't need to be saved). So I want to add an input field without having it tied to a table field, and it seems that's something FileMaker just doesn't do.
Two use cases:
a) I want a custom search/filter interface instead of using the FM one. My users should see two calendars, pick two dates and the data is filtered by those (between them), as well as additional criteria, which don't directly translate to field searches. I know I can use "startdate ... enddate", but I'd like a more user-friendly interface.
b) Users enter a few data points into seperate fields which are then computed and combined into one database field by script. This is technical data that is entered by copy-and-paste and needs a bit of parsing before I put it into the database. Again, I'd like a field that isn't related to the database, put a script trigger on it, and when data is entered there, it is parsed and put into the actual DB fields.
Is it possible at all to have input fields not related to a database in FileMaker ?
If not, what's the best practice? I thought about setting up a dummy table with various fields I can use, but maybe there's a better way?
You should read up on global fields. They can be in any table and are accessible from all tables. They do not retain their value after the session is closed if the file is hosted. Use a script to perform a search based on what the user types in the global field.

Elastic search "InnerHits" Vs Doing an extra call

Currently i am having product(child) and supplier(parent) types which have parent-child relationship.In scenario where i need to show the natched products with there respective suppliers i am using "innerhits" to fetch the supplier(parent) along with product(child), which is working fine.
But now i have gone through an article which says that "innerhits" slows up the query.so now i am having an alternate approach which is to make a single call to supplier(parent) type and fetch all the suppliers for the needed products.
BRIEFLY PUTTING : (InnerHits) Vs (making separate call), which of the two approaches is advisable.

Is there a way to sort a content query by the value of a field programmatically?

I'm working on a portal based on Orchard CMS. We're using Orchard to manage the "normal" content of the site, as well as to model what's essentially data for a small application embedded in it.
We figured that doing it that way is "recommended" for working in Orchard, and that it would save us duplicating a bunch of effort in features that Orchard already provides, mainly generating a good enough admin UI. This is also why we're using fields wherever possible.
However, for said application, the client wants to be able to display the data in the regular UI in a garden-variety datagrid that can be filtered, sorted, and paged.
I first tried to implement this by cobbling together a page with a bunch of form elements for the filtering, above a projection with filters bound to query string parameters. However, I ran into the following issues with this approach:
Filters for numeric fields crash when the value is missing - as would be pretty common to indicate that the given field shouldn't be considered when filtering. (This I could achieve by changing the implementation in the Orchard source, which would however make upgrading trickier later. I'd prefer to keep anything I haven't written untouched.)
It seems the sort order can only be defined in the administration UI, it doesn't seem to support tokens to allow for the field to sort by to be changed when querying.
So I decided to dump that approach and switched to trying to do this with just MVC controllers that access data using IContentQuery. However, there I found out that:
I have no clue how, if at all, it's possible to sort the query based on field values.
Or, for that matter, how / if I can filter.
I did take a look at the code of Orchard.Projections, however, how it handles sorting is pretty inscrutable to me, and there doesn't seem to be a straightforward way to change the sort order for just one query either.
So, is there any way to achieve what I need here with the rest of the setup (which isn't little) unchanged, or am I in a trap here, and I'll have to move every single property I wish to use for sorting / filtering into a content part and code the admin UI myself? (Or do something ludicrous, like create one query for every sortable property and direction.)
EDIT: Another thought I had was having my custom content part duplicate the fields that are displayed in the datagrids into Hibernate-backed properties accessible to query code, and whenever the content item is updated, copy values from these fields into the properties before saving. However, again, I'm not sure if this is feasible, and how I would be able to modify a content item just before it's saved on update.
Right so I have actually done a similar thing here to you. I ended up going down both approaches, creating some custom filters for projections so I could manage filters on the frontend. It turned out pretty cool but in the end projections lacked the raw querying power I needed (I needed to filter and sort based on joins to aggregated tables which I think I decided I didn't know how I could do that in projections, or if its nature of query building would allow it). I then decided to move all my data into a record so I could query and filter it. This felt like the right way to go about it, since if I was building a UI to filter records it made sense those records should be defined in code. However, I was sorting on users where each site had different registration data associated to users and (I think the following is a terrible affliction many Orchard devs suffer from) I wanted to build a reusable, modular system so I wouldn't have to change anything, ever!
Didn't really work out quite like I hoped, but to eventually answer the question in your title: yes, you can query fields. Orchard projections builds an index that it uses for querying fields. You can access these in HQL, get the ids of the content items, then call getmany to get them all. I did this several years ago, and I cant remember much but I do remember having a distinctly unenjoyable time with it haha. So after you have an nhibernate session you can write your hql
select distinct civr.Id
from Orchard.ContentManagement.Records.ContentItemVersionRecord civr
join civ.ContentItemRecord cir
join ci.FieldIndexPartRecord fipr
join fipr.StringFieldIndexRecord sfir
This just shows you how to join to the field indexes. There are a few, for each different data type. This is the string one I'm joining here. They are all basically the same, with a PropertyName and value field. Hql allows you to add conditions to your join so we can use that to join with the relevant field index records. If you have a part called Group attached directly to your content type then it would be like this:
join fipr.StringFieldIndexRecord sfir
with sfir.PropertyName = 'MyContentType.Group.'
where sfir.Value = 'HR'
If your field is attached to a part, replace MyContentType with the name of your part. Hql is pretty awesome, can learn more here: https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/queryhql.html But I dunno, it gave me a headache haha. At least HQL has documentation though, unlike Orchard's query layer. Also can always fall back to pure SQL when HQL wont do what you want, there is an option to write SQL queries from the NHibernate session.
Your other option is to index your content types with lucene (easy if you are using fields) then filter and search by that. I quite liked using that, although sometimes indexes are corrupted, or need to be rebuilt etc. So I've found it dangerous to rely on it for something that populates pages regularly.
And pretty much whatever you do, one query to filter and sort, then another query to getmany on the contentmanager to get the content items is what you should accept is the way to go. Good luck!
You can use indexing and the Orchard Search API for this. Sebastien demoed something similar to what you're trying to achieve at Orchard Harvest recently: https://www.youtube.com/watch?v=7v5qSR4g7E0

Search in default_collection minus a specific collection

In our GSA index of 500K documents half of the documents are coming from an internal bug tracking system.
We have been hearing some power users complain about results from the bug tracking system pushing down other useful results from many other sources.
We discussed about using result biasing to lower the importance of bug tracking documents but I am not very keen on this approach as I believe we should let GSA do its magic and decide on the relevancy of the results.
Instead what I want to provide users as an option is a UI (checkbox for each collection) where they can pick what collections they want to perform the search.
My non-default collections does not include everything that is under the default_collection. So when user checks each and every checkbox they may think that that is everything in the index while it is not.
Because of this I want the checkboxes to behave as exclude rather than include (i,e. check to exclude this collection).
Finally my question: Is there a way to search in the default collection but filter out results that belong to a specific collection (bug tracking collection).
When you want to use multiple collections you do &site=col1|col2|col3..
What I am after is something like &site=default_collection-col1 (that's a minus in between).
Is there a way to do this?
Any alternative approaches to this problem?
Personally, I would rethink the design of your collections and build more modular collections that you can include. That way as you mentioned you can include OR queries in your site include.
http://www.google.com/support/enterprise/static/gsa/docs/admin/70/gsa_doc_set/xml_reference/request_format.html#1076953
A less ideal but more specific solution to your problem is going to be do an exclude by URL in your search query, be aware this can appear in results query search box and looks ugly, but this can be fixed using a simple XSLT change.
To exclude results for a specific site (http://www.google.com/support/enterprise/static/gsa/docs/admin/70/gsa_doc_set/xml_reference/request_format.html#1076964) I would use this sparingly and opt for better design of the collections.
By far the best way to do this is in your collection config. Just create a new collection that has the same include pattern as your default collection and add the pattern from your bug tracking collection as an exclude pattern.
There's no way to do what you're asking purely using query parameters unless you list out every individual collection using the '|' except the one you want and then you're likely to run in to URL length issues.
Update your frontend to exclude the url patterns mentioned for the bugtracking collection.
check this url on your box
http://yourGSAEnterpriseCcontroller:8000/EnterpriseController/serve_remove.html

Resources