List of all Child B2BUnits - sap-commerce-cloud

How to write a Flexible search Query to list all the Child B2BUnits of a Parent B2BUnit?
Ex: Parent B2BUnit: tc-0100
Child B2BUnit: tc-0101,tc-0102
If I search for Parent B2BUnit(tc-0100), I should get all the Child B2BUnits(tc-0101,tc-0102)

You can get all the children of the given b2bUnit(i.e tc-0100) with the following query:
select {pk} from {B2BUnit} where {pk} in ({{select {source} from {PrincipalGroupRelation} where {target}='$pkOfParentUnit$'}})
This flexible search query can be tried in hac after replacing $pkOfParentUnit$ with the actual PK of the given unit tc-0100 (the PK can be seen in the "Administration" tab in backoffice)
Explanation:
The inner query :
({{select {source} from {PrincipalGroupRelation} where {target}='$pkOfParentUnit$'}})
fetches all the members of a group(and in our case all the members of the given B2B unit) including B2BCustomers that might be assigned to it.
The beginning of the query makes sure that only the B2BUnits are present in the result and not B2BCustomers or other objects that might be also members.

Related

Writing a subquery to display records in a grid

I have two DAC's POReceipt, and and POReceiptLine. POReceiptLine containts a field called MfrPartNbr.
I want the user to be able to lookup all the POReceipts where the POReceiptLine.MfrPartNbr is equal to an entered value.
The SQL would be
SELECT *
FROM dbo.POReceipt
WHERE POReceipt.ReceiptNbr IN
(
SELECT ReceiptNbr
FROM dbo.POReceiptLine
WHERE MfrPartNbr = 'MY_ENTERED_PART_NBR'
)
Any idea how to write the BQL Statement for this?
As stated, an inner join won't work in this case because you will receive the same POReceipt multiple times (once for each POReceiptLine). The following BQL query shows how you can get the desired results using a sub query. If mfrPartNbr is an extension field, then replace POReceiptLine.mfrPartNbr with the correct extension name (e.g. POReceiptLineExtension.mfrPartNbr).
PXSelect<POReceipt, Where<Exists<
Select<POReceiptLine,
Where<POReceiptLine.receiptNbr, Equal<POReceipt.receiptNbr>,
And<POReceiptLine.mfrPartNbr, Equal<Required<POReceiptLine.mfrPartNbr>>>>>>>>.Select(this, "MY_ENTERED_PART_NBR");

Get all documents within a folder or site that has a specific Aspect property value?

I have an aspect that I have associated with multiple documents. For example lests call the aspect OrderAspect.
The below query works when I fetch all nodes that have a location property from OrderAspect set to 'WAREHOUSE-A'
SELECT * FROM oa:OrderAspect WHERE oa:Location ='WAREHOUSE-A'
How can I extend this query to get ONLY documents that have this aspect value as 'WAREHOUSE-A'.
Can I extend this query to search within a folder path or site? I would like to list all the documents within a folder (including subfolder) or a site that has OrderAspect with property location set to 'WAREHOUSE-A'.
Here is how you do a CMIS query that restricts results to a value defined in an aspect:
select D.cmis:name from cmis:document as D join sc:temp as T on D.cmis:objectId = T.cmis:objectId where T.sc:prop1 = 'value1'
Here is how you add an AND clause to require that the result be in a certain path, including sub-folders:
select D.cmis:name from cmis:document as D join sc:temp as T on D.cmis:objectId = T.cmis:objectId where T.sc:prop1 = 'value1' AND CONTAINS(D, 'PATH:\"/app:company_home/st:sites/cm:jtp-test-site-1/cm:documentLibrary//*\"')

Using a Lucene Filter to restrict items based on a list

I have a list of categories, e.g. 1000, 1001, 1002, 1003, etc... and users have access to only some of these categories. I want to filter my lucene.net search results based on only categories that the user has access to, or to omit results for items they don't have access to.
I have tried using the Lucene FieldCacheTermsFilter but this returns no results at all:
New Lucene.net.search.FieldCacheTermsFilter("category", {"1000", "1002"} )
Is there a better way to filter results based on a particular field having a value that exists in a list?
I solved this by using a BooleanQuery wrapper around my main query in all cases.
I took my originaly search query (MainQuery) and created a new BooleanQuery using occur.must for that and my security query as below:
dim SecurityQuery as New lucene.net.search.BooleanQuery( )
For Each id as string in AllowedIDs
q.Add(New TermQuery(New Lucene.Net.Index.Term("category", s)), Occur.SHOULD)
Next
Dim FinalQuery As New lucene.net.search.BooleanQuery( )
FinalQuery.Add( MainQuery, occur.must )
FinalQuery.Add( SecurityQuery, occur.must )
This doesn't use a Filter, so I am unsure as to whether this is the best performing option. But it works.

Create edge from attribute with ArangoDB AQL

I have imported a list of documents (in a collection named "assemblies"). One of the attributes is "parent_id".
Based on this, I want to construct the graph, that is implicitly described by this attribute.
"id","name","parent_id"
"30","Top level"
"30.1","30.1 Child 1","30"
"30.2","30.2 Child 2","30"
This is the query, that I expected to give me the info for creating the edge collection (named "contains", so it is from parent to child):
FOR assy IN assemblies
LET parent = (
FOR parent IN assemblies
FILTER parent.id == assy.parent_id
RETURN parent
)
RETURN {_from: parent._key, _to: assy._key}
What am I doing wrong? Could you give me the full query for inserting the edges?
The problem is that the result of your subquery in parent is an array and not an document. But there is actually no need of a subquery. You can also performe a join, which should offer better performance and is easier to read.
You also have to use the value of _id insteadt of _key for the fields _from and _to of your edges.
The following query does exactly what you want.
FOR assy IN assemblies
FOR parent IN assemblies
FILTER parent.id == assy.parent_id
INSERT {_from: parent._id, _to: assy._id} IN contains
RETURN NEW
Node: the RETURN NEW is optional. You can check with it whether the import was successful. With larger amount of data I would drop this.

loopback relational database hasManyThrough pivot table

I seem to be stuck on a classic ORM issue and don't know really how to handle it, so at this point any help is welcome.
Is there a way to get the pivot table on a hasManyThrough query? Better yet, apply some filter or sort to it. A typical example
Table products
id,title
Table categories
id,title
table products_categories
productsId, categoriesId, orderBy, main
So, in the above scenario, say you want to get all categories of product X that are (main = true) or you want to sort the the product categories by orderBy.
What happens now is a first SELECT on products to get the product data, a second SELECT on products_categories to get the categoriesId and a final SELECT on categories to get the actual categories. Ideally, filters and sort should be applied to the 2nd SELECT like
SELECT `id`,`productsId`,`categoriesId`,`orderBy`,`main` FROM `products_categories` WHERE `productsId` IN (180) WHERE main = 1 ORDER BY `orderBy` DESC
Another typical example would be wanting to order the product images based on the order the user wants them to
so you would have a products_images table
id,image,productsID,orderBy
and you would want to
SELECT from products_images WHERE productsId In (180) ORDER BY orderBy ASC
Is that even possible?
EDIT : Here is the relationship needed for an intermediate table to get what I need based on my schema.
Products.hasMany(Images,
{
as: "Images",
"foreignKey": "productsId",
"through": ProductsImagesItems,
scope: function (inst, filter) {
return {active: 1};
}
});
Thing is the scope function is giving me access to the final result and not to the intermediate table.
I am not sure to fully understand your problem(s), but for sure you need to move away from the table concept and express your problem in terms of Models and Relations.
The way I see it, you have two models Product(properties: title) and Category (properties: main).
Then, you can have relations between the two, potentially
Product belongsTo Category
Category hasMany Product
This means a product will belong to a single category, while a category may contain many products. There are other relations available
Then, using the generated REST API, you can filter GET requests to get items in function of their properties (like main in your case), or use custom GET requests (automatically generated when you add relations) to get for instance all products belonging to a specific category.
Does this helps ?
Based on what you have here I'd probably recommend using the scope option when defining the relationship. The LoopBack docs show a very similar example of the "product - category" scenario:
Product.hasMany(Category, {
as: 'categories',
scope: function(instance, filter) {
return { type: instance.type };
}
});
In the example above, instance is a category that is being matched, and each product would have a new categories property that would contain the matching Category entities for that Product. Note that this does not follow your exact data scheme, so you may need to play around with it. Also, I think your API query would have to specify that you want the categories related data loaded (those are not included by default):
/api/Products/13?filter{"include":["categories"]}
I suggest you define a custom / remote method in Product.js that does the work for you.
Product.getCategories(_productId){
// if you are taking product title as param instead of _productId,
// you will first need to find product ID
// then execute a find query on products_categories with
// 1. where filter to get only main categoris and productId = _productId
// 2. include filter to include product and category objects
// 3. orderBy filter to sort items based on orderBy column
// now you will get an array of products_categories.
// Each item / object in the array will have nested objects of Product and Category.
}

Resources