<!-- 
RSS generated by JIRA (1001.0.0-SNAPSHOT#100246-sha1:7a5c50119eb0633d306e14180817ddef5e80c75d) at Thu Feb 08 23:09:24 UTC 2024

It is possible to restrict the fields that are returned in this document by specifying the 'field' parameter in your request.
For example, to request only the issue key and summary add field=key&field=summary to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>FOLIO Jira</title>
    <link>https://folio-org.atlassian.net</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>1001.0.0-SNAPSHOT</version>
        <build-number>100246</build-number>
        <build-date>07-02-2024</build-date>
    </build-info>

<item>
            <title>[MODINVSTOR-27] Join requirements for items-holdings-instances</title>
                <link>https://folio-org.atlassian.net/browse/MODINVSTOR-27</link>
                <project id="10139" key="MODINVSTOR">mod-inventory-storage</project>
                    <description>&lt;p&gt;Specify the business logic requirements for searching, sorting (and details display) and thus for joining items, holdings and instances and possibly the set of reference tables. &lt;/p&gt;

&lt;p&gt;There are two main join scenarios: &lt;/p&gt;

&lt;ul&gt;
	&lt;li&gt;&quot;small scale join&quot; where the client needs just the few holdings and items associated with an instance for example and would like to have type references translated from UUIDs to type labels  (ie &apos;ISBN&apos; or &apos;sound recording&apos;).&lt;/li&gt;
	&lt;li&gt;&quot;large scale join&quot; where large data sets of instances, holdings and items are brought up, joined and sorted.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Small scale joins &amp;#8211; ie pulling in reference table translations &amp;#8211; could conceivably be done in business logic module. Large scale joins more likely on the database level. &lt;/p&gt;

</description>
                <environment></environment>
        <key id="55583">MODINVSTOR-27</key>
            <summary>Join requirements for items-holdings-instances</summary>
                <type id="10002" iconUrl="https://folio-org.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10322?size=medium">New Feature</type>
                                            <priority id="10002" iconUrl="https://dev.folio.org/assets/jira-priority/jira-p3.svg">P3</priority>
                        <status id="1" iconUrl="https://folio-org.atlassian.net/images/icons/statuses/open.png" description="The issue is open and ready for the assignee to start work on it.">Open</status>
                    <statusCategory id="2" key="new" colorName="blue-gray"/>
                                    <resolution id="-1">Unresolved</resolution>
                                                        <assignee accountid="-1">Unassigned</assignee>
                                                                <reporter accountid="5bffed5e2434bf3a1a91d37a">Niels Erik Nielsen</reporter>
                                    <labels>
                            <label>core</label>
                    </labels>
                <created>Tue, 14 Nov 2017 11:26:56 +0000</created>
                <updated>Tue, 15 Jan 2019 11:53:45 +0000</updated>
                                                                                <due></due>
                            <votes>0</votes>
                                    <watches>3</watches>
                                                    <timespent seconds="15300">4 hours, 15 minutes</timespent>
                                <comments>
                                                            <comment id="131175" author="5bffed5e2434bf3a1a91d37a" created="Wed, 15 Nov 2017 13:03:10 +0000"  >&lt;p&gt;I&apos;m not entirely clear on whether we&apos;re developing the Codex search, or a native Inventory search, or both at this point. &lt;/p&gt;

&lt;p&gt;The Codex search would not require any joins  (assuming that the Codex API is basically our instance record minus a few fields)&lt;/p&gt;

&lt;p&gt;The Inventory UX prototype so far has one suggestion (which is just a suggestion at this point) for filtering, that would require a potentially somewhat large scale join between &apos;instance&apos; and &apos;holdings-record&apos;  (filtering by location). This would be beyond the Codex requirements afaict. But I can spec that out in pseudo code or something. &lt;/p&gt;

&lt;p&gt;There is nothing in the UX yet that seems to require a three-way join between &apos;instance&apos;, &apos;holdings-record&apos; and &apos;item&apos;.  I don&apos;t know if there will be. We have a &apos;format&apos; on &apos;item&apos; for example. Searching by format could result in a very large join, but would we need to search on that, since we also have instance-format and instance-type on &apos;instance&apos;? I could spec it out regardless, though. &lt;/p&gt;

&lt;p&gt;I suppose we could eventually make use of a three-way join for the very distinct search of items by barcode. I can make an example of that too. &lt;/p&gt;</comment>
                                                            <comment id="131183" author="5bffed5e2434bf3a1a91d37a" created="Wed, 15 Nov 2017 13:37:36 +0000"  >&lt;p&gt;Searching for instances by location (from &apos;holdings-record&apos; table that does not yet exist):&lt;/p&gt;

&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
find instance(attributes)  
from instance and holdings-record, joined on instance.uuid
where   holdings-record(location) = &lt;span class=&quot;code-quote&quot;&gt;&apos;some location&apos;&lt;/span&gt;  
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;location could be a UUID, so potentially a join with a &apos;location&apos; table as well. &lt;/p&gt;

&lt;p&gt;Finding an instance (one that would be) by item barcode:&lt;/p&gt;
&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
find instance(attributes) and holdings(location, callnumber, holdingsstatements) and item (format, status, temp location, barcode)
from instance and holdings-record and item, joined on instance UUID and holdings UUID
where item.barcode = &lt;span class=&quot;code-quote&quot;&gt;&apos;some barcode&apos;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Searching for instances by item format (??): &lt;/p&gt;

&lt;div class=&quot;code panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;codeContent panelContent&quot;&gt;
&lt;pre class=&quot;code-java&quot;&gt;
find instance(attributes) 
from instance and holdings-record and item, joined on instance UUID and holdings UUID
where item.formatID = &lt;span class=&quot;code-quote&quot;&gt;&apos;some UUID&apos;&lt;/span&gt;
&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As for sorting, we&apos;re so far displaying title, creators(repeated), identifiers(repeated), publishers(repeated), publication dates(repeated). Guess these would be the initial sorting candidates for instances results lists. &lt;/p&gt;


</comment>
                                                            <comment id="131186" author="712020:32bb56ac-50e7-4787-b4af-ed3089d9401c" created="Sun, 3 Dec 2017 12:11:54 +0000"  >&lt;p&gt;cases 2 and 3 seem to be very similar (bar-code matching / format matching)&lt;/p&gt;

&lt;p&gt;data population: (existing indexes in mod-inv-storage not shown here, fields that need to be searchable / sortable need indexes as well)&lt;/p&gt;

&lt;div class=&quot;preformatted panel&quot; style=&quot;border-width: 1px;&quot;&gt;&lt;div class=&quot;preformattedContent panelContent&quot;&gt;
&lt;pre&gt;  INSERT INTO cql7_mod_inventory_storage.holdings_record
  SELECT id, 
  jsonb_build_object(
	&apos;id&apos;, id, 
	&apos;instanceId&apos;, instance_id , 
	&apos;permanentLocationId&apos; ,  permanentLocationId)
  FROM (select gen_random_uuid() AS id , generate_series(10000000, 13000001) || &apos;-a3e4-465c-82f1-acade4e8e170&apos; as instance_id , 
        &apos;d9cd0bed-1b49-4b5e-a7bd-064b8d17723&apos; || trunc(random() * 9) as permanentLocationId) as alias;   
  

  INSERT INTO cql7_mod_inventory_storage.instance
  SELECT id, 
  jsonb_build_object(
      &apos;id&apos;, id, 
      &apos;title&apos;, title, 
      &apos;source&apos; , source, 
      &apos;edition&apos; , edition, 
      &apos;instanceTypeId&apos; , &apos;2b94c631-fca9-a892-c730-03ee529ffe2c&apos;,
  	  &apos;creators&apos;, json_build_array(jsonb_build_object(&apos;name&apos;, &apos;ari sigal&apos; , &apos;creatorTypeId&apos; , &apos;2b94c631-fca9-a892-c730-03ee529ffe2a&apos;)))
  FROM (select (generate_series(10000000, 13000001) || &apos;-a3e4-465c-82f1-acade4e8e170&apos;)::uuid AS id ,
        (md5(random()::text)) || &apos; l&#246;rd the root  &apos;  || (md5(random()::text)) AS title,
        (md5(random()::text)) as source,  trunc(random() * 20) || &apos; ed.&apos; as edition) as alias;   
  

  INSERT INTO cql7_mod_inventory_storage.item
  SELECT id, 
  jsonb_build_object(
      &apos;id&apos;, id, 
      &apos;barcode&apos; ,  barcode , 
      &apos;status&apos; , jsonb_build_object(&apos;name&apos;, barcode || &apos;21ag&apos;),     
      &apos;materialTypeId&apos; , &apos;1c302429-5d78-4f8b-a367-3437bf1ab56e&apos;, 
      &apos;permanentLoanTypeId&apos;, &apos;2c302429-5d78-4f8b-a367-3437bf1ab56e&apos;,
  	  &apos;temporaryLoanTypeId&apos;, &apos;2c302429-5d78-4f8b-a367-3437bf1ab56e&apos;, 
      &apos;title&apos;, title, 
      &apos;permanentLocationId&apos; , permanentLocationId)
  FROM (select gen_random_uuid() AS id , 
        trunc(random() * 200000) || &apos;g&apos; AS barcode,  
        ((md5(random()::text)) || &apos; zeev shalev &apos;  || (md5(random()::text))) AS title,
        (generate_series(10000000, 13000001) || &apos;-a3e4-465c-82f1-acade4e8e170&apos;)::uuid AS permanentLocationId) as alias;   
		
 //Searching for instances by location		
  CREATE OR REPLACE VIEW cql7_mod_inventory_storage.instance_holding_view AS 
  select 
   u._id,u.jsonb as jsonb, g.jsonb as h_jsonb from cql7_mod_inventory_storage.instance u  
   join 
   cql7_mod_inventory_storage.holdings_record g on lower(f_unaccent(u.jsonb-&amp;gt;&amp;gt;&apos;id&apos;)) = lower(f_unaccent(g.jsonb-&amp;gt;&amp;gt;&apos;instanceId&apos;))
   
  //Finding an instance (one that would be) by item barcode:
  CREATE OR REPLACE VIEW cql7_mod_inventory_storage.item_instance_holding_view AS 
  select 
  it._id,it.jsonb as jsonb, ho.jsonb as h_jsonb, ins.jsonb as ins_jsonb from cql7_mod_inventory_storage.instance ins  
   join cql7_mod_inventory_storage.holdings_record ho on lower(f_unaccent(ins.jsonb-&amp;gt;&amp;gt;&apos;id&apos;)) = lower(f_unaccent(ho.jsonb-&amp;gt;&amp;gt;&apos;instanceId&apos;))
   join cql7_mod_inventory_storage.item it on lower(f_unaccent(it.jsonb-&amp;gt;&amp;gt;&apos;permanentLocationId&apos;)) = lower(f_unaccent(ho.jsonb-&amp;gt;&amp;gt;&apos;instanceId&apos;))
    

INDEXES 
instance  (lower(f_unaccent(jsonb-&amp;gt;&amp;gt;&apos;id&apos;)));
item  (lower(f_unaccent(jsonb-&amp;gt;&amp;gt;&apos;permanentLocationId&apos;)));
holdings_record (lower(f_unaccent(jsonb-&amp;gt;&amp;gt;&apos;instanceId&apos;)));
holdings_record using gin (lower ( f_unaccent(jsonb-&amp;gt;&amp;gt;&apos;permanentLocationId&apos;))  gin_trgm_ops);

&lt;/pre&gt;
&lt;/div&gt;&lt;/div&gt;


&lt;p&gt;QUERIES&lt;/p&gt;

&lt;p&gt;//find instances by location&lt;br/&gt;
select *  FROM cql7_mod_inventory_storage.instance_holding_view  WHERE lower(f_unaccent(instance_holding_view.h_jsonb-&amp;gt;&amp;gt;&apos;permanentLocationId&apos;)) ~ lower(f_unaccent(&apos;d9cd0bed&apos;)) ORDER BY lower(f_unaccent(instance_holding_view.jsonb-&amp;gt;&amp;gt;&apos;title&apos;)) limit 30 ;&lt;/p&gt;

&lt;p&gt;//Finding an instance (one that would be) by item barcode: (SORT BY FIELDS IN INSTANCE TABLE ONLY!)&lt;br/&gt;
select ins_jsonb from cql7_mod_inventory_storage.item_instance_holding_view where lower(f_unaccent(jsonb-&amp;gt;&amp;gt;&apos;barcode&apos;)) ~ &apos;5f0bc5&apos;   limit 10;&lt;/p&gt;

&lt;p&gt;select ins_jsonb from cql7_mod_inventory_storage.item_instance_holding_view where lower(f_unaccent(jsonb-&amp;gt;&amp;gt;&apos;barcode&apos;)) ~ &apos;5f0bc5a84750f6be3358f03330f02&apos; order by lower(f_unaccent(ins_jsonb-&amp;gt;&amp;gt;&apos;title&apos;))  limit 10;&lt;/p&gt;</comment>
                                                            <comment id="131190" author="712020:32bb56ac-50e7-4787-b4af-ed3089d9401c" created="Sun, 3 Dec 2017 12:19:17 +0000"  >&lt;p&gt;this view can be added manually (writing the actual sql) in the schema.json.&lt;br/&gt;
support for this declaratively will be supported with issue 
    &lt;span class=&quot;jira-issue-macro resolved&quot; data-jira-key=&quot;RMB-104&quot; &gt;
                &lt;a href=&quot;https://folio-org.atlassian.net/browse/RMB-104&quot; class=&quot;jira-issue-macro-key issue-link&quot;  title=&quot;optimize join views + add support for more than 2 tables&quot; &gt;
            &lt;img class=&quot;icon&quot; src=&quot;https://folio-org.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10318?size=medium&quot; /&gt;
            RMB-104
        &lt;/a&gt;
                                                    &lt;span class=&quot;aui-lozenge aui-lozenge-subtle aui-lozenge-success jira-macro-single-issue-export-pdf&quot;&gt;Closed&lt;/span&gt;
            &lt;/span&gt;
&lt;/p&gt;</comment>
                    </comments>
                <issuelinks>
                            <issuelinktype id="10000">
                    <name>Blocks</name>
                                                                <inwardlinks description="is blocked by">
                                        <issuelink>
            <issuekey id="55742">MODINVSTOR-25</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="60195">MODINV-16</issuekey>
        </issuelink>
                            </inwardlinks>
                                    </issuelinktype>
                            <issuelinktype id="10003">
                    <name>Relates</name>
                                            <outwardlinks description="relates to">
                                        <issuelink>
            <issuekey id="46736">UIIN-3</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="46693">UIIN-5</issuekey>
        </issuelink>
                            </outwardlinks>
                                                                <inwardlinks description="relates to">
                                        <issuelink>
            <issuekey id="47179">CIRC-49</issuekey>
        </issuelink>
            <issuelink>
            <issuekey id="46688">UIIN-32</issuekey>
        </issuelink>
                            </inwardlinks>
                                    </issuelinktype>
                    </issuelinks>
                <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_10000" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummarycf">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10057" key="com.atlassian.jira.plugin.system.customfieldtypes:select">
                        <customfieldname>Development Team</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="10144"><![CDATA[Core: Platform]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_10019" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>0|hzy2z3:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_10020" key="com.pyxis.greenhopper.jira:gh-sprint">
                        <customfieldname>Sprint</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        <customfield id="customfield_10024" key="com.atlassian.jira.ext.charting:firstresponsedate">
                        <customfieldname>[CHART] Date of First Response</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>Sun, 3 Dec 2017 12:11:54 +0000</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                </customfields>
    </item>
</channel>
</rss>