Skip to content

Commit

Permalink
version 2.06.02
Browse files Browse the repository at this point in the history
  • Loading branch information
ppawliczek committed Mar 26, 2018
1 parent 3265e63 commit 384096f
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 22 deletions.
60 changes: 59 additions & 1 deletion src/ruby/brl/genboree/kb/stats/abstractStats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ def initialize(mdb)
:avgByteSize => "The average number of bytes used across all documents in a kb or across all documents in a collection",
:lastEditTime => "The time the last edit was made to a kb or one of its collection",
:lastEditAuthor => "The author of the last edit to the kb or one of its collections",
:allPointStats => "All of the following statistics as a property-oriented document: #{POINT_STATS.map{|xx| xx.to_s}.join(", ")}."
:allPointStats => "All of the following statistics as a property-oriented document: #{POINT_STATS.map{|xx| xx.to_s}.join(", ")}.",
:lastNEditedDocs => "The last N edited documents in a collection. Response will include doc identfier, version number and timestamp."
}
OPTION_DESCRIPTIONS = {
:resolution => "For over-time statistics, a frequency for calculating the statistic: one of \"minute\", \"hour\", \"day\", \"month\", or \"year\", defaults to \"month\"",
Expand Down Expand Up @@ -163,6 +164,19 @@ def docCountOverTime(opts={})
opts = defaultOpts.merge(opts)
return statWrapperOverTime(:docCountOverTime, opts)
end

def lastNEditedDocs(opts={})
@warnings = []
@errors = []
defaultOpts = {
:title => "Number of Documents",
:yAxis => "# Docs",
:units => "Documents",
:seriesNames => ["Documents"]
}
opts = defaultOpts.merge(opts)
return statWrapper(:lastNEditedDocs, opts)
end

# @todo rename versions to actions for public interfaces?
def versionCount(opts={})
Expand Down Expand Up @@ -556,6 +570,50 @@ def numCollDocsInRangeByRes(timeRange, coll=nil)
count = numCollCreatesInRange(timeRange, coll) - numCollDeletesInRange(timeRange, coll)
end
alias :numCollDocsInRange :numCollDocsInRangeByRes

def lastNEditedDocsInColl(coll=nil, ndocs=3)
setDch(coll)
setVh(coll)
gbIdName = @dch.getIdentifierName()
gbIdPath = "versionNum.properties.content.value.#{gbIdName}.value"
docRefName = "docRef"
docRefPath = "versionNum.properties.#{docRefName}.value"

# define aggregation pipeline
pipeline = []
matchConfig = { "versionNum.properties.deletion.value" => false }
match = { "$match" => matchConfig }
pipeline << match

group = {
"$group" => {
GROUP_KEY => {
docRefName => "$#{docRefPath}"
},
"docId" => {
"$first" => "$#{gbIdPath}"
},
"version" => {
"$max" => "$versionNum.value"
},
"timestamp" => {
"$max" => "$versionNum.properties.timestamp.value"
}
}
}
pipeline << group
sort = {
"$sort" => {"version" => -1 }
}
pipeline << sort
limit = {
"$limit" => ndocs
}
pipeline << limit
$stderr.debugPuts(__FILE__, __method__, "DEBUG", "Making aggregate request on #{@vh.coll.name.inspect} defined by pipeline:\n#{JSON.pretty_generate(pipeline)}")
resp = @vh.coll.aggregate(pipeline)
return resp
end

# Count the number of data documents affected by edits for a time range
# @see numCollVersionsInRange
Expand Down
3 changes: 2 additions & 1 deletion src/ruby/brl/genboree/kb/stats/allCollStats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ class AllCollStats < AbstractStats
:versionCountOverTime => :mapCollVersionsInRange,
:createCountOverTime => :mapCollCreatesInRange,
:editCountOverTime => :mapCollEditsInRange,
:deleteCountOverTime => :mapCollDeletesInRange
:deleteCountOverTime => :mapCollDeletesInRange,
:lastNEditedDocs => :lastNEditedDocsInColl
}

#--------------------------------------------------
Expand Down
6 changes: 5 additions & 1 deletion src/ruby/brl/genboree/kb/stats/collStats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ def statWrapper(stat, opts={})
raiseAnyErrors()
retVal = {}
chart = /^hc/.match(opts[:format].to_s) ? true : false
retVal = self.send(STAT_TO_METHOD[stat])
if(stat != :lastNEditedDocs)
retVal = self.send(STAT_TO_METHOD[stat])
else
retVal = self.send(STAT_TO_METHOD[stat], nil, ( opts.key?(:ndocs) ? opts[:ndocs] : 3 ))
end
retVal = cleanStatData(retVal)
if(chart)
retVal = chartData(retVal, opts)
Expand Down
3 changes: 2 additions & 1 deletion src/ruby/brl/genboree/kb/stats/kbStats.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ class KbStats < AbstractStats
:versionCountOverTime => :mapKbVersionsInRange,
:createCountOverTime => :mapKbCreatesInRange,
:editCountOverTime => :mapKbEditsInRange,
:deleteCountOverTime => :mapKbDeletesInRange
:deleteCountOverTime => :mapKbDeletesInRange,
:lastNEditedDocs => :lastNEditedDocsInColl
}

##################
Expand Down
83 changes: 65 additions & 18 deletions src/ruby/brl/genboree/rest/resources/kbDocProp.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,12 @@ def initOperation()
@docName = Rack::Utils.unescape(@uriMatchData[4])
@propPath = Rack::Utils.unescape(@uriMatchData[5])
raise BRL::Genboree::GenboreeError.new(:"Bad Request", "property path cannot be nil or empty. Please provide a valid property path") if(@propPath.nil? or @propPath == "")
# Look for limit/skip/count when retrieving items under item lists
@limit = @nvPairs.key?("limit") ? @nvPairs["limit"].to_i : nil
@skip = @nvPairs.key?("skip") ? @nvPairs["skip"].to_i : nil
@count = @nvPairs.key?("count") ? @nvPairs["count"].to_i : nil
raise BRL::Genboree::GenboreeError.new(:"Bad Request", "Please provide either skip and limit or only count") if(!@limit.nil? and !@skip.nil? and !@count.nil?)

# Optional Parameter for performing a no-op put/delete
@save = ( ( @nvPairs['save'] and @nvPairs['save'] == 'false' ) ? false : true )
# @todo: test and enable the save=false option
Expand Down Expand Up @@ -73,7 +79,26 @@ def initOperation()
if(docNameValidation and docNameValidation[:result] == :VALID) # looks compatible and has now been casted appropriately
@docName = docNameValidation[:castValue] # use casted value
#$stderr.debugPuts(__FILE__, __method__, "DEBUG", "DOC NAME NOW: #{@docName.inspect}")
@doc = dataHelper.getByIdentifier(@docName, { :doOutCast => true, :castToStrOK => true })
@doc = nil
# If retrieving only specific items in a list, get everything but the list for setting up @doc
if(@count or (@skip and @limit))
modelPathEls = []
@propPathEls = @propPath.split(".")
@propPathEls.each { |el|
if(el !~ /\[/ and el !~ /\{/)
modelPathEls << el
end
}
mongoPath = @mh.modelPath2DocPath(modelPathEls.join("."), @collName)
mongoPath.gsub!(/value$/, "items")
cc = dataHelper.coll.find({"#{@identifierProp}.value" => @docName}, {:fields => { mongoPath => 0 } })
cc.each { |dd|
dd.delete("_id")
@doc = dd
}
else
@doc = dataHelper.getByIdentifier(@docName, { :doOutCast => true, :castToStrOK => true })
end
unless(@doc)
raise BRL::Genboree::GenboreeError.new(:"Not Found", "The document #{@docName} was not found in the collection #{@collName}")
end
Expand All @@ -91,28 +116,50 @@ def get()
propSel = BRL::Genboree::KB::PropSelector.new(@doc)
entity = nil
begin
$stderr.debugPuts(__FILE__, __method__, "DEBUG", "beginning get()")
propObj = propSel.getMultiObj(@propPath)
if(@propPath =~ /\]$/)
unless(@aspect)
entity = BRL::Genboree::REST::Data::KbDocEntity.new(@connect, propObj[0])
else
if(@aspect == 'value')
itemRootProp = propObj[0].keys[0]
entity = BRL::Genboree::REST::Data::KbDocEntity.new(@connect, { "value" => propObj[0][itemRootProp]['value'] })
end
end
#$stderr.debugPuts(__FILE__, __method__, "DEBUG", "beginning get()\n@doc: #{JSON.pretty_generate(@doc)}")
# For skip and limit or count, get specific items under a list
# Only works for properties that are an item list
if((@skip and @limit) or @count)
propPath = propSel.getMultiPropPaths(@propPath)[0]

raise BRL::Genboree::GenboreeError.new(:"Bad Request", "Property path #{@propPath} could not be found in doc #{@docName}. Please check the property path you provided.") if(propPath.nil?)
opts = {
:count => @count,
:skip => @skip,
:limit => @limit
}
retVal = @dataHelper.sliceSubDocItemList(propPath, @docName, opts)
# Extract the 'items' from the returned object since this resource returns the value object pointed to by the property path
# To extract the items from the returned object, change the index of all item lists leading to the final list to be 0 since the query has sliced all the item lists preceeding the final one and kept only the one parent item
newPropPath = propPath.gsub(/\[\d+\]/, "[0]")
retVal.delete("_id")
propSel2 = BRL::Genboree::KB::PropSelector.new(retVal)
items = propSel2.getMultiPropItems(newPropPath)
payloadDoc = { "items" => items}
entity = BRL::Genboree::REST::Data::KbDocEntity.new(@connect, payloadDoc)
else
valueObj = propObj[0][propObj[0].keys[0]]
unless(@aspect)
entity = BRL::Genboree::REST::Data::KbDocEntity.new(@connect, valueObj)
propObj = propSel.getMultiObj(@propPath)
if(@propPath =~ /\]$/)
unless(@aspect)
entity = BRL::Genboree::REST::Data::KbDocEntity.new(@connect, propObj[0])
else
if(@aspect == 'value')
itemRootProp = propObj[0].keys[0]
entity = BRL::Genboree::REST::Data::KbDocEntity.new(@connect, { "value" => propObj[0][itemRootProp]['value'] })
end
end
else
if(@aspect == 'value')
entity = BRL::Genboree::REST::Data::KbDocEntity.new(@connect, { "value" => valueObj['value'] })
valueObj = propObj[0][propObj[0].keys[0]]
unless(@aspect)
entity = BRL::Genboree::REST::Data::KbDocEntity.new(@connect, valueObj)
else
if(@aspect == 'value')
entity = BRL::Genboree::REST::Data::KbDocEntity.new(@connect, { "value" => valueObj['value'] })
end
end
end
$stderr.debugPuts(__FILE__, __method__, "DEBUG", "setting md")
end
$stderr.debugPuts(__FILE__, __method__, "DEBUG", "setting md")
docRef = @dataHelper.getDocRefFromDocName(@model['name'], @docName)
metadata = @dataHelper.getMetadata(docRef, nil, @propPath)
entity.setMetadata(metadata)
Expand Down
2 changes: 2 additions & 0 deletions src/ruby/brl/genboree/rest/resources/kbStat.rb
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,8 @@ def mungeOpts(opts)
opts[:yAxis] = "# Docs"
elsif(@stat == 'docCount')
opts[:title] = "# Docs Per Collection"
elsif(@stat == 'lastNEditedDocs' and @nvPairs.key?('ndocs'))
opts[:ndocs] = @nvPairs['ndocs'].to_i
end
return opts
end
Expand Down

0 comments on commit 384096f

Please sign in to comment.