<!-- 
RSS generated by JIRA (9.7.1#970001-sha1:2222b88b221c4928ef0de3161136cc90c8356a66) at Wed Feb 07 21:36: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 append 'field=key&field=summary' to the URL of your request.
-->
<rss version="0.92" >
<channel>
    <title>MongoDB Jira</title>
    <link>https://jira.mongodb.org</link>
    <description>This file is an XML representation of an issue</description>
    <language>en-us</language>    <build-info>
        <version>9.7.1</version>
        <build-number>970001</build-number>
        <build-date>13-04-2023</build-date>
    </build-info>


<item>
            <title>[CSHARP-292] There should be a way to join several UpdateBuilder instances into a complete update expression (IMongoUpdate)</title>
                <link>https://jira.mongodb.org/browse/CSHARP-292</link>
                <project id="10041" key="CSHARP">C# Driver</project>
                    <description>&lt;p&gt;For example a new constructor of UpdateDocument: UpdateDocument(IEnumerable&amp;lt;UpdateBuilder&amp;gt;).&lt;/p&gt;

&lt;p&gt;UpdateBuilder chains do not cover all practical scenarios well. My application creates update pieces for each field separately. Pseudo code:&lt;/p&gt;

&lt;p&gt;UpdateBuilder Method1() &lt;/p&gt;
{ return Update.Set(&quot;filed1&quot;, value1); }
&lt;p&gt;UpdateBuilder Method2() &lt;/p&gt;
{ return Update.Set(&quot;filed2&quot;, value2); }
&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;As a result, in a method that calls Method1, Method2, ..., MethodN I have a collection of update expressions, one per a field. The driver does not provide an easy way to join these pieces into a single update expression to be used in Update() methods. Instead, we have to create a starter empty UpdateBuilder, send it to all methods, and methods have to be a bit more complex:&lt;/p&gt;

&lt;p&gt;UpdateBuilder Method1(UpdateBuilder builder) &lt;/p&gt;
{ return builder.Set(&quot;filed1&quot;, value1); }
&lt;p&gt;UpdateBuilder Method2(UpdateBuilder builder) &lt;/p&gt;
{ return builder.Set(&quot;filed2&quot;, value2); }
&lt;p&gt;...&lt;/p&gt;

&lt;p&gt;&quot;&quot;&quot;&quot;&quot; Real scenario: it shows that even Method(UpdateBuilder) approach is not enough for all &quot;&quot;&quot;&quot;&quot;&lt;/p&gt;

&lt;p&gt;In fact, my application is a PowerShell module designed for MondoDB + C# driver.&lt;br/&gt;
In scripts I would like to be able to perform commands like this:&lt;/p&gt;

&lt;p&gt;Update-Data $collection $query @(&lt;br/&gt;
    Set-Value filed1 value1&lt;br/&gt;
    Set-Value filed2 value2&lt;br/&gt;
    Set-Value filedN valueN&lt;br/&gt;
)&lt;/p&gt;

&lt;p&gt;The last argument of Update-Data cmdlet (it calls Update() on $collection) is a collection of update expressions produced by one or more calls of the Set-Value cmdlet (gets an update expression for a single field).&lt;/p&gt;

&lt;p&gt;But this desirable code is now not supported due to lack of a proposed driver method. I cannot even use Method(UpdateBuilder) approach because the expression @(..) is evaluated before the call to Update-Data and there is no chance to initiate a starter UpdateBuilder to be sent to Set-Value cmdlets even implicitly (say, as a hidden internal variable shared between Set-Value calls).&lt;/p&gt;

&lt;p&gt;Instead, I have to make the Set-Value cmdlet to accept optional UpdateBuilder input via pipeline. So that I have to emulate UpdateBuilder chains in a peculiar way. And the code above right now actually has to look like this:&lt;/p&gt;

&lt;p&gt;Update-Data $collection $query ( `&lt;br/&gt;
    Set-Value filed1 value1 |&lt;br/&gt;
    Set-Value filed2 value2 |&lt;br/&gt;
    Set-Value filedN valueN&lt;br/&gt;
)&lt;/p&gt;

&lt;p&gt;So that the first call to Set-Value initiates a starter UpdateBuilder and sends it to other Set-Value-s. The required UpdateBuilder chain is emulated.&lt;/p&gt;

&lt;p&gt;Well, it is not that bad and the job is done. But it is not pretty either:&lt;/p&gt;

&lt;p&gt;*) Pipelines (|) are basically expensive in PowerShell and better be avoided&lt;br/&gt;
*) Syntax is not so easy and neat like it could be (version 1 is much better)&lt;br/&gt;
*) It all gets more difficult if a script wants to call these Set-Value in different places, collect results in some $updates variable (a collection) and then only to call:&lt;/p&gt;

&lt;p&gt;Update-Data $collection $query $updates&lt;/p&gt;

&lt;p&gt;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&quot;&lt;/p&gt;

&lt;p&gt;Of course, I can go to lower level and do that $set, etc. things on my own. But I think the purpose of the driver is to do such low level jobs and let users to concentrate on their application code instead. Ideally, a user of C# driver should not have to know MongoDB query/update expression syntax details.&lt;/p&gt;</description>
                <environment></environment>
        <key id="20322">CSHARP-292</key>
            <summary>There should be a way to join several UpdateBuilder instances into a complete update expression (IMongoUpdate)</summary>
                <type id="4" iconUrl="https://jira.mongodb.org/secure/viewavatar?size=xsmall&amp;avatarId=14710&amp;avatarType=issuetype">Improvement</type>
                                            <priority id="4" iconUrl="https://jira.mongodb.org/images/icons/priorities/minor.svg">Minor - P4</priority>
                        <status id="6" iconUrl="https://jira.mongodb.org/images/icons/statuses/closed.png" description="The issue is considered finished, the resolution is correct. Issues which are closed can be reopened.">Closed</status>
                    <statusCategory id="3" key="done" colorName="success"/>
                                    <resolution id="9">Done</resolution>
                                        <assignee username="robert@mongodb.com">Robert Stam</assignee>
                                    <reporter username="nightroman">Roman Kuzmin</reporter>
                        <labels>
                    </labels>
                <created>Sun, 31 Jul 2011 06:54:49 +0000</created>
                <updated>Thu, 2 Apr 2015 18:27:39 +0000</updated>
                            <resolved>Fri, 5 Aug 2011 23:21:05 +0000</resolved>
                                                    <fixVersion>1.2</fixVersion>
                                    <component>Feature Request</component>
                                        <votes>0</votes>
                                    <watches>0</watches>
                                                                                                                <comments>
                            <comment id="46767" author="nightroman" created="Sat, 6 Aug 2011 06:39:32 +0000"  >&lt;p&gt;Robert,&lt;/p&gt;

&lt;p&gt;Thank you. This is exactly what I was asking for. As a result, I got rid of my extra helper class. All now works in simple and natural way.&lt;/p&gt;

&lt;p&gt;NB: It was needed for C# API in the first place. PowerShell was mentioned just as an example of a scenario that triggered the issue. The new Combine() method I actually consume in C# (but for PowerShell, yes).&lt;/p&gt;</comment>
                            <comment id="46747" author="rstam" created="Fri, 5 Aug 2011 23:21:05 +0000"  >&lt;p&gt;The static method Update.Combine combines a variable number of UpdateBuilders into one single new UpdateBuilder. The instance method UpdateBuilder.Combine combines one other UpdateBuilder into an existing UpdateBuilder.&lt;/p&gt;

&lt;p&gt;I assume the static method will do what you wanted to do in Powershell. Let me know if it does not.&lt;/p&gt;</comment>
                            <comment id="45454" author="nightroman" created="Sun, 31 Jul 2011 08:40:12 +0000"  >&lt;p&gt;OK, I have found a way to make desirable syntax to work in PowerShell scripts. But this is rather rocket science comparing to how easy it could be instead if we are able to join update expressions &lt;img class=&quot;emoticon&quot; src=&quot;https://jira.mongodb.org/images/icons/emoticons/smile.png&quot; height=&quot;16&quot; width=&quot;16&quot; align=&quot;absmiddle&quot; alt=&quot;&quot; border=&quot;0&quot;/&gt;. So the ticket suggestion is still valid.&lt;/p&gt;

&lt;p&gt;Here it is, just in case if anybody interested.&lt;/p&gt;

&lt;p&gt;=1=&lt;br/&gt;
I introduced a class:&lt;br/&gt;
    public class UpdateField&lt;br/&gt;
    {&lt;br/&gt;
        public Func&amp;lt;UpdateBuilder, UpdateBuilder&amp;gt; Build &lt;/p&gt;
{ get; private set; }
&lt;p&gt;        public UpdateField(Func&amp;lt;UpdateBuilder, UpdateBuilder&amp;gt; build)&lt;/p&gt;
        {
            Build = build;
        }
&lt;p&gt;        public override string ToString()&lt;/p&gt;
        {
            return Build(new UpdateBuilder()).ToString();
        }
&lt;p&gt;    }&lt;/p&gt;

&lt;p&gt;=2=&lt;br/&gt;
Cmdlets Set-Value, etc. now emit not UpdateBuilder objects (as it used to be straightforward) but new UpdateField objects with attached delegates that do actual calls to Set, Inc, Push, Pull, etc. (more convoluted).&lt;/p&gt;

&lt;p&gt;=3=&lt;br/&gt;
Cmdlet Update-Data (that calls Update()) joins one or more input UpdateField objects by creating an UpdateBuilder and calling Build on every UpdateField, thus, chaining them, as far as chaining is the only possible way to build a complex update expression.&lt;/p&gt;

&lt;p&gt;All in all, now I can do this in PowerShell:&lt;/p&gt;

&lt;p&gt;Update-Data $collection $query @( &lt;br/&gt;
    Set-Value filed1 value1 &lt;br/&gt;
    Set-Value filed2 value2 &lt;br/&gt;
    Set-Value filedN valueN &lt;br/&gt;
)&lt;/p&gt;

&lt;p&gt;Or even more dynamic (with true chain/pipeline approach that would not be so easy):&lt;/p&gt;

&lt;p&gt;Update-Data $collection $query @(&lt;br/&gt;
    Set-Value filed1 value1&lt;br/&gt;
    if (something) &lt;/p&gt;
{
        Set-Value filed2 value2
    }
&lt;p&gt;    Set-Value filedN valueN&lt;br/&gt;
)&lt;/p&gt;</comment>
                    </comments>
                    <attachments>
                    </attachments>
                <subtasks>
                    </subtasks>
                <customfields>
                                                                                                                                                                                                                        <customfield id="customfield_10011" key="com.atlassian.jira.plugin.system.customfieldtypes:radiobuttons">
                        <customfieldname>Backwards Compatibility</customfieldname>
                        <customfieldvalues>
                                <customfieldvalue key="10038"><![CDATA[Fully Compatible]]></customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                <customfield id="customfield_15850" key="com.atlassian.jira.plugins.jira-development-integration-plugin:devsummary">
                        <customfieldname>Development</customfieldname>
                        <customfieldvalues>
                            
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    <customfield id="customfield_12550" key="com.pyxis.greenhopper.jira:gh-lexo-rank">
                        <customfieldname>Rank</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>2|hrh8l3:</customfieldvalue>

                        </customfieldvalues>
                    </customfield>
                                                                <customfield id="customfield_10558" key="com.pyxis.greenhopper.jira:gh-global-rank">
                        <customfieldname>Rank (Obsolete)</customfieldname>
                        <customfieldvalues>
                            <customfieldvalue>14190</customfieldvalue>
                        </customfieldvalues>
                    </customfield>
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            </customfields>
    </item>
</channel>
</rss>