Realm Studio - how to filter by linked objects - realm

When using Realm Studio, filtering by data columns on a collection works, however, filtering by a linked record does not seem to? I have tried both the syntax in the linked documentation as well as a variety of other attempts and guesses.
For example, my Schema has links to a "Component" object. I'd like to filter all the records that link to a specific Component. I have attempted the documented component.id == 123 as well as many variations such as component_id = 123, Component == $0, 123, componentId == [c] "123", and many more.
What am I doing wrong?

Related

Function of Rows, Rowsets in PeopleCode

I'm trying to get a better understanding of what Rows and Rowsets are used for in PeopleCode? I've read through PeopleBooks and still don't feel like I have a good understanding. I'm looking to get more understanding of these as it pertains to Application Engine programs. Perhaps walking through an example may help. Here are some specific questions I have:
I understand that Rowsets, Row, Record, and Field are used to access component buffer data, but is this still the case for stand alone Application Engine programs run via Process Scheduler?
What would be the need or advantage to using these as opposed to using SQL objects/functions (CreateSQL, SQLExec, etc...)? I often see in AE programs where the CreateRowset object is instantiated and uses a .Fill method with a SQL WHERE Clause and I don't quite understand why a SQL was not used instead.
I've seen in PeopleBooks that a Row object in a component scroll is a row, how does a component scroll relate to the row? I've seen references to rows having different scroll levels, is this just a way of grouping and nesting related data?
After you have instantiated the CreateRowset object, what are typical uses of it in the program afterwards? How would you perform logic (If, Then, Else, etc..) on data retrieved by the rowset, or use it to update data?
I appreciate any insight you can share.
You can still use Rowsets, Rows, Records and fields in stand alone Application Engines. Application Engines do not have component buffer data as they are not running within the context of a component. Therefore to use these items you need to populate them using built-in methods like .fill() on a rowset, or .selectByKey() on a record.
The advantage of using rowsets over SQL is that it makes the CRUD easier. There are built-in methods for selecting, updating, inserting and deleting. Additionally you don't have to worry about making a large number of variables if there were multiple fields like you would with a SQL object. Another advantage is when you do the fill, the data is read into memory, where if you looped through the SQL, the SQL cursor would be open longer. The rowset, row, record and field objects also have a lot of other useful methods such as allowing you to executeEdits (validation) or copy from one rowset\row\record to another.
This question is a bit less clear to me but I'll try and explain. If you have a Page, it would have a level 0 row. It then could have multiple Level 1 rowsets. Under each of those it could have a level 2 rowsets.
Level0
/ \
Level1 Level1
/ \ / \
Level2 Level2 Level2 Level2
If one of your level1 rows had 3 rows, then you would find 3 rows in the Rowset associated with that level1. Not sure I explained this to answer what you need, please clarify if I can provide more info
Typically after I create a rowset, I would loop through it. Access the record on each row, do some processing with it. In the example below, I look through all locked accounts and prefix their description with LOCKED and then updated the database.
.
Local boolean &updateResult;
local integer &i;
local record &lockedAccount;
Local rowset &lockedAccounts;
&lockedAccounts = CreateRowset(RECORD.PSOPRDEFN);
&lockedAccounts.fill("WHERE acctlock = 1");
for &i = 1 to &lockedAccounts.ActiveRowCount
&lockedAccount = &lockedAccounts(&i).PSOPRDEFN;
if left(&lockedAccount.OPRDEFNDESCR.value,6) <> "LOCKED" then
&lockedAccount.OPRDEFNDESCR.value = "LOCKED " | &lockedAccount.OPRDEFNDESCR.value;
&updateResult = &lockedAccount.update();
if not &updateResult then
/* Error handle failed update */
end-if;
end-if;
End-for;

Querying multiple project names Odata Feeds in Project Server 2013

I am trying to query multiple projects in an Odata feed for our project server, but I have been unsuccessful so far. I am able to get individual project names and even exclude them, but when I try to query more than one project name I do not get the results I want. Perhaps my syntax is wrong. Any help with this would be greatly appreciated..
When I run this one it breaks and tells me that 'and' is an unknown operator:
http://$server/pwa/_api/ProjectData/Projects$filter=ProjectName -eq 'name1' and 'name2'
When I run this one it runs, but it still only looks at one value:
http://$server/pwa/_api/ProjectData/Projects$filter=ProjectName -eq 'name1' & 'name2'
According to this article this would be the right syntax the above statement using AND, but I am told that the syntax is wrong.
https://msdn.microsoft.com/en-us/library/ff478141.aspx
Also I even read this article to start with, which is a general overview of odata queries, but this is not really answering my question.
https://msdn.microsoft.com/en-us/library/office/jj163048.aspx
I think there are a few changes you may need to make to get this to work the way you want:
The property name on the PublishedProject entity, according to the $metadata, is 'Name' and not 'ProjectName'.
Using conditional AND means that the project name would have to equal both 'name1' AND 'name2'. I think you really want conditional OR, so that the project name equals either 'name1' OR 'name2'
You need two full expressions joined by conditional OR in order to filter for projects with 'name1' or 'name2'.
'-eq' is the wrong syntax for an equality expression. Drop the hyphen and use just 'eq' (this is shown in the examples on the MSDN page you linked to.)
So your filter changes to:
?$filter=Name eq 'name1' or Name eq 'name2'
Or, the Url-encoded form:
?$filter=Name+eq+'name1'+or+Name+eq+'name2'
Optionally, you can use grouping in this query to make it a little easier to read:
?$filter=(Name eq 'name1') or (Name eq 'name2')
Disclaimer: I've only verified these filter examples work on a Project Online instance, not 2013.
#RyanY I figured out just realized what I did wrong It was a problem with the logic I was using. Just as you said my syntax was wrong. I had checked earlier and no one answered my post. I was about to answer my own question just now and I saw your post..lol
To get my result I was looking for all I have to do is issue a REST query such as this:
http://$server/pwa/_api/ProjectData/Projects$filter=ProjectName eq 'name1' or ProjectName eq 'name2' or ProjectName eq 'name3'..ect
I like this idea btw I'll use that in the future its much more organized: ?$filter=(Name eq 'name1') or (Name eq 'name2')
Thanks for the feedback. Also my real name is Ryan too. What a coincidence :)

element-attribute-range-query fetching result but element-attribute-value-query is not fetching any result

I wanted to fetch the document which have the particular element attribute value.
So, I tried the cts:element-attribute-value-query but I didn't get any result. But the same element attribute value, I am able to get using cts:element-attribute-range-query.
Here the sample snippet used.
let $s-query := cts:element-attribute-range-query(xs:QName("tit:title"),xs:QName("name"),"=",
"SampleTitle",
("collation=http://marklogic.com/collation/codepoint"))
let $s-query := cts:element-attribute-value-query(xs:QName("tit:title"),xs:QName("name"),
"SampleTitle",
())
return cts:search(fn:doc(),($s-query))
The problem with range-query is it needs the range index. I have hundreds of DB's in multiple hosts. I need to create range indexes on each DB.
What could be the problem with attribute-value-query?
I found the issue with a couple of research.
Actually the result document is a french language document. It has the structure as follows. This is a sample.
<doc xml:lang="fr:CA" xmlns:tit="title">
<tit:title name="SampleTitle"/>
</doc>
The cts:element-attribute-value-query is a language dependent query. To get the french language results, then language needs to be mentioned in the option as follows.
cts:element-attribute-value-query(xs:QName("tit:title"),xs:QName("name"), "SampleTitle",("lang=fr"))
But cts:element-attribute-range-query don't require the language option.
Thanks for the effort.

Selecting data in Firebase

Saw the Firebase / Angular video you did and immediately got very excited about the project I have just started. One thing I am struggling to get my head around is how to select data at sub-levels. What I mean is: say I had something like this:
How can I select all records with the agent 'agent_1' and/or records with the box_id greater than 600 (plus other fields) without creating lots of indexes for each search term? I don't really want to download all the data to the client and then loop through the records as there will eventually be a lot of data.
Eventually, the app should be able to filter data on different fields simultaneously. For example, I would have a select box for agents, which may return all the agent_1 records. Then I would add the filter 'all boxes with id > 600' and then perhaps 'box weight > 24kg' etc.
It seems from what I have read, this is only possible by having an id field for each record, and then an index dataset for each field one would like to search against. This is simple enough for one field. However, I guess the only way to filter the data with further fields would be to get the ids on the next index dataset and do the filtering on the client.
Am I right in this approach? It seems quite long-winded.
What would be awesome would be to be able to do this:
https://xxxxx.firebaseio.com/boxes/?agent=agent_1/?box_id>600
Just a thought! :-)
Thanks!
first Import angular like following
import { AngularFireDatabase } from "angularfire2/database";
also import in app.module.ts
secondly inject database into your constructor an like
constructor(private database:AngularFireDatabase ){
const rootRef = database.database.ref();
var data= rootRef.child("boxes").orderByChild("agent").equalTo("agent_3")
}

What does Managed="0" in List view XML mean?

I've written a Data Extender class and editor extension that properly displays a few additional columns for items as you browse lists in the CME (folders and structure groups). I had to register my class to handle commands like GetList, GetListSearch, GetListUserFavorites, and GetListCheckedOutItems.
What I've noticed is that the code gets run even when a list of say, schemas is loaded for a drop-down list in the CME (like when creating a new component and you get the list of schemas in a drop-down). so, even though my additional data columns aren't needed in that situation, the code is still being executed and it slows things down.
It seems that it's the GetList command called in those situations. So, I can't just skip processing based on the command. So, I started looking at the XML that the class receives for the list and I've noticed when the code is run for the drop-downs, there's a Managed="0" in the XML. For example:
For a Structure Group list: <tcm:ListItems Managed="64" ID="tcm:103-546-4">
For a Folder list: <tcm:ListItems Managed="16" ID="tcm:103-411-2">
But for a Schema list: <tcm:ListItems ID="tcm:0-103-1" Managed="0">
For a drop-down showing keyword values for a category: <tcm:ListItems Managed="0" ID="tcm:103-506-512">
So, can I just use this Managed="0" as a flag to indicate that the list being processed isn't going to show my additional columns and I can just quit processing?
Managed value is representation of what items can be created inside OrganizationItem:
64 means you can create pages
16 means you can create components
10, for example would mean you can create folders (2) + schemas (8)
518 - folders (2) + structure groups (4) + categories (512)
The value is 0 for non organizational items.
Value depends on the item itself (you can't create pages in folder, for example), as well as on security settings you have on publication and organizational item
Unfortunately CME can't offer right now that kind of granularity level to allow you to tell in a data extender where a particular WCF API call is coming from. Our WCF API is not context aware yet. It may change in the future.
Trusting Managed="0" is not a great idea.
The reason for that is the model lists are client cached per filter. In the current design the filter has CM related data and nothing related to the context the request is being fired from.
Typically the client user interface is reusing cached model data whenever is possible. For instance the same model list could be used in the CME dashboard and a drop down control placed into some item view, but with different xml list definitions: the first one will have more columns defined in the list definition than the latter. They are basically different views of the same data.
Therefore you may want to think of different solutions for your problem.
Now... where is the data behind those additional columns is coming from? Is it Tridion CM or a third party provider?
Sometimes the web server caching may provide an acceptable way to improve the response times. But that's the kind of design you should evaluate and decide upon.
I think you would have a more robust solution if you read the ID of the list, and only execute your code for lists of type 2 and 4 (Folders and Structure Groups respectively). but that won't help you with search views etc.
From previous experience and what User978511 says the Managed attribute is an indication of item types that can be created from the context of that list.
Unfortunately that means that the Managed attribute may well be 0 for any user that doesn't have sufficient rights to create items. E.g. check what Managed is in a Structure Group for a user that isn't allowed to create Pages or Structure Groups. It may well be 0 in that case too, meaning it is useless for your situation.
Update
You may be able to reach your goal better by looking at the columns parameter:
context.Parameters["columns"]
In a few tests I've run I get different values, depending on whether I get a list for the main list view, the tree or a drop down list.
543
23
7
Those values are a bit mask of these constants (from Constants.js):
/**
* Defines the column filter.
* Used to specify which attributes should be included in XML list data.
* #enum
*/
Tridion.Constants.ColumnFilter =
{
ID: 1,
ID_AND_TITLE: 3,
DEFAULT: 7,
EXTENDED: 15,
ALLOWED_ACTIONS: 16,
VERSIONS: 32,
INTERNALS: 64,
URL: 128,
XML_NAME: 256,
CHECK_OUT_USER: 512,
PUBTITLE_AND_ITEM_PATH: 1024
};
So from my limited testing it seems that drop downs request DEFAULT columns, while the main list view and the tree both have ALLOWED_ACTIONS in there. This makes sense to me, since the user gets can interact with the list items in the tree and list view, while they can only select them in the drop downs. So checking for the presence of ALLOWED_ACTIONS in the columns parameter might be one way to reduce the number of places where your data extender adds information.

Resources