Skip to content

Implements #7921 extend query to support latest versions#7923

Merged
sebastienros merged 10 commits into
OrchardCMS:1.10.xfrom
LaserSrl:issue/7921_Extend_Query_To_Support_LatestVersions
Jan 4, 2018
Merged

Implements #7921 extend query to support latest versions#7923
sebastienros merged 10 commits into
OrchardCMS:1.10.xfrom
LaserSrl:issue/7921_Extend_Query_To_Support_LatestVersions

Conversation

@HermesSbicego-Laser

Copy link
Copy Markdown
Contributor

Implements #7921, branched from #7920 cause we need the LatestValue column to be there.
When a query is created/edited it is possible to specify the Content Version to query (Published or Latest).
Based on that choice the HqlQuery will filter

  • the right VersionOption
  • the right column of the (*)IndexFilterRecord

Based on that choice the HqlQuery will order

  • using the right column of the (*)IndexFilterRecord

- Adds Indexes to increase performances in queries
- Adds Handler to store LatestValue during Update event
- Adds Service to Get and Set the LatestValue of a field
- Adds heavy projections index tables update to the Upgrade module
…e part's lifecycle

- Manage Queries using ScopeVersion informations

return 5;
}
public int UpdateFrom5() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move to UpdateFrom4. And update the Create method to create the table correctly including all subsequent changes, then return 5.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I will threat this PR and the #7920 one as they were the same PR, so I can aggregate UpdateFrom4 and 5

SchemaBuilder.AlterTable("DecimalFieldIndexRecord", table => table
.AddColumn<decimal>("LatestValue"));

//Adds indexes for better performances in queries

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two comments:

  • We need to talk about the "necessity" of these indices
  • You are reusing the same index name multiple times, is it an issue? should it be unique per database, or no otherwise table prefix would break it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • Necessity of these indexes: do you mean SQL indexes or the "LatestValue" columns? For SQL indexes, I think at least IX_FieldIndexPartRecord_Id should be created because it is a foreign key "in fact". The index over PropertyName column is for projections and HqlQueries so I think they should be there. I don't see a good reason why they shouldn't be there
  • Same index name: I seem to remember that Indexes name should be unique per table and not per database. At least in SQL Server, so i don't see an issue here. Perhaps it's not the same in MySql or Postgre?


// generate the predicate based on the editor which has been used
Action<IHqlExpressionFactory> predicate = fieldTypeEditor.GetFilterPredicate(context.State);
dynamic fullState = context.State;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why dynamic ? You can't access the VersionScope property directly?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fieldTypeEditor.GetFilterPredicate (2 lines above) method use a dynamic parameter as input. I need that information within IFieldTypeEditor.GetFilterPredicate in order to return the right column (Value or LatestValue) to query.

? context.Query.OrderBy(relationship, x => x.Asc("Value"))
: context.Query.OrderBy(relationship, x => x.Desc("Value"));
context.Query = ascending
? context.Query.OrderBy(relationship, x => x.Asc(context.VersionScope == QueryVersionScopeOptions.Latest ? "LatestValue" : "Value"))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe create a method in the context to get the field name (based on the scope). I have seen this multiple times.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, i will try

Query = groupQuery,
State = FormParametersHelper.ToDynamic(sortCriterion.State)
State = FormParametersHelper.ToDynamic(sortCriterion.State),
VersionScope = queryRecord.VersionScope

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of duplicating this property in all context objects, can't we just pass the parent Query which already has the value?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean to add the QueryPart to the context?

@using Orchard.Projections;

<fieldset>
@Html.LabelFor(m => m.VersionScope, T("Query Version Scope"))

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Version Scope" is not very intuitive. "Versions" only seems better. What do we use in Lucene indices?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok for "Versions", or "Content versions"?

}

[HttpPost, ActionName("Index")]
public ActionResult IndexPOST() {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't it do it by batch of content items? If there are too many of them this will fail. There are some examples doing it in other upgrade controllers.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you address me to an example where I can copy from? thanks.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found it by myself in InfosetController.cs

}
private void Updated(UpdateContentContext context, FieldIndexPart fieldIndexPart) {
if (context.UpdatingItemVersionRecord.Latest) { // updates projection draft indexes only if it is the latest version
foreach (var part in fieldIndexPart.ContentItem.Parts) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Try to externalize this method, and use a lambda as the differences.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK, I will try...

using Orchard.Projections.Models;

namespace Orchard.Projections.Services {
public class DraftFieldIndexService : IDraftFieldIndexService {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I understand this is to prevent a breaking change. But I'd prefer to see it merged into the existing service in the dev branch. Can you file an issue for this? I will assign it for 1.11.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, i will do it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

opened issue #7925

…lterContext and SortCriteriaContext: used in ProjectionManager

- Adds a method which returns the columnName to Sort/Filter to FilterContext and SortCriteriaContext: used in ContentFieldsSortCriteria
- Externalize the logic to calculate the column to index
- Merge Update 4 and 5
- Modified the label "Query Version Scope" into "Content's version"
@BenedekFarkas

Copy link
Copy Markdown
Member

Does the code expect that the Query's version scope can only be Published or All? I'm asking because #8111.

@HermesSbicego-Laser

Copy link
Copy Markdown
Contributor Author

In this PR, the Query's version scope can be Published or Latest.

@HermesSbicego-Laser

Copy link
Copy Markdown
Contributor Author

@BenedekFarkas I read a bit the code in your #8112 PR. Adding the filter on the right versionOption of the content is not sufficient. Should be changed other code. In particular where we test the VersionOption in order to choose the right column (Value/LatestValue) to check/order.
see:

  1. https://github.com/OrchardCMS/Orchard/pull/7923/files#diff-2e5f3c3cb7233e791056952d3b891828
  2. https://github.com/OrchardCMS/Orchard/pull/7923/files#diff-718cbbbafe30601793f25355e00903f1
  3. classes implementing IFieldTypeEditor

@BenedekFarkas

Copy link
Copy Markdown
Member

@HermesSbicego-Laser good point, I only saw the addition of LatestValue after submitting my PR - I'll look into it and update accordingly, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants