activedocument 0.5 → 0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -221,7 +221,12 @@ module ActiveDocument
|
|
221
221
|
else
|
222
222
|
root_namespace = namespace_for_element(root)
|
223
223
|
end
|
224
|
-
|
224
|
+
if arguments[6]
|
225
|
+
options = arguments[6]
|
226
|
+
else
|
227
|
+
options = nil
|
228
|
+
end
|
229
|
+
execute_attribute_finder(element, attribute, value, root, element_namespace, attribute_namespace, root_namespace, options)
|
225
230
|
elsif method =~ /find_by_(.*)$/ and arguments.length > 0 # identify element search methods
|
226
231
|
value = arguments[0]
|
227
232
|
element = $1.to_sym
|
@@ -240,7 +245,14 @@ module ActiveDocument
|
|
240
245
|
else
|
241
246
|
root_namespace = namespace_for_element(root)
|
242
247
|
end
|
243
|
-
|
248
|
+
if arguments[4]
|
249
|
+
options = arguments[4]
|
250
|
+
else
|
251
|
+
options = nil
|
252
|
+
end
|
253
|
+
execute_finder(element, value, root, element_namespace, root_namespace, options)
|
254
|
+
else
|
255
|
+
super
|
244
256
|
end
|
245
257
|
|
246
258
|
end
|
@@ -49,14 +49,14 @@ module ActiveDocument
|
|
49
49
|
end
|
50
50
|
end
|
51
51
|
|
52
|
-
def self.execute_finder(element, value, root = nil, element_namespace = nil, root_namespace = nil)
|
53
|
-
xquery = @@xquery_builder.find_by_element(element, value, root, element_namespace, root_namespace)
|
52
|
+
def self.execute_finder(element, value, root = nil, element_namespace = nil, root_namespace = nil, options = nil)
|
53
|
+
xquery = @@xquery_builder.find_by_element(element, value, root, element_namespace, root_namespace, options)
|
54
54
|
@@log.info("Finder.execute_finder at line #{__LINE__}: #{xquery}")
|
55
55
|
SearchResults.new(@@ml_http.send_xquery(xquery))
|
56
56
|
end
|
57
57
|
|
58
|
-
def self.execute_attribute_finder(element, attribute, value, root = nil, element_namespace = nil, attribute_namespace = nil, root_namespace = nil)
|
59
|
-
xquery = @@xquery_builder.find_by_attribute(element, attribute, value, root, element_namespace, attribute_namespace, root_namespace)
|
58
|
+
def self.execute_attribute_finder(element, attribute, value, root = nil, element_namespace = nil, attribute_namespace = nil, root_namespace = nil, options = nil)
|
59
|
+
xquery = @@xquery_builder.find_by_attribute(element, attribute, value, root, element_namespace, attribute_namespace, root_namespace, options)
|
60
60
|
@@log.info("Finder.execute_attribute_finder at line #{__LINE__}: #{xquery}")
|
61
61
|
SearchResults.new(@@ml_http.send_xquery(xquery))
|
62
62
|
end
|
@@ -11,7 +11,7 @@
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
12
|
# See the License for the specific language governing permissions and
|
13
13
|
# limitations under the License.
|
14
|
-
|
14
|
+
require 'ActiveDocument/mark_logic_search_options'
|
15
15
|
module ActiveDocument
|
16
16
|
# todo create new unit tests for this class - the old ones were no good
|
17
17
|
class MarkLogicQueryBuilder
|
@@ -26,77 +26,47 @@ module ActiveDocument
|
|
26
26
|
|
27
27
|
def save(document, uri)
|
28
28
|
xquery = <<-GENERATED
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
GENERATED
|
35
|
-
|
29
|
+
xdmp:document-insert(
|
30
|
+
"#{uri}",
|
31
|
+
#{document.to_s} ,
|
32
|
+
xdmp:default-permissions(),
|
33
|
+
xdmp:default-collections())
|
34
|
+
GENERATED
|
36
35
|
end
|
37
36
|
|
38
37
|
# This method does a full text search
|
39
|
-
def find_by_word(word, root,
|
38
|
+
def find_by_word(word, root, root_namespace, options = nil)
|
40
39
|
xquery = <<-GENERATED
|
41
|
-
import module namespace search = "http://marklogic.com/appservices/search"at "/MarkLogic/appservices/search/search.xqy";
|
40
|
+
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
|
42
41
|
search:search("#{word}",
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
xquery << " xmlns:a=\"#{namespace}\"" unless namespace.nil? or namespace.empty?
|
49
|
-
xquery << '>/'
|
50
|
-
xquery << "a:" unless namespace.nil? or namespace.empty?
|
51
|
-
xquery << "#{root}</searchable-expression>"
|
52
|
-
end
|
53
|
-
xquery << "</options>)"
|
42
|
+
GENERATED
|
43
|
+
search_options = setup_options(options, root, root_namespace)
|
44
|
+
xquery << search_options.to_s
|
45
|
+
xquery << ')'
|
54
46
|
end
|
55
47
|
|
56
|
-
def find_by_element(element, value, root, element_namespace, root_namespace)
|
48
|
+
def find_by_element(element, value, root, element_namespace, root_namespace, options = nil)
|
57
49
|
xquery = <<-GENERATED
|
58
50
|
import module namespace search = "http://marklogic.com/appservices/search"at "/MarkLogic/appservices/search/search.xqy";
|
59
|
-
search:search("
|
60
|
-
<options xmlns="http://marklogic.com/appservices/search">
|
51
|
+
search:search('find_by_element:\"#{value}\"',
|
61
52
|
GENERATED
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
xquery << "a:" unless root_namespace.nil?
|
67
|
-
xquery << "#{root}</searchable-expression>"
|
68
|
-
end
|
69
|
-
xquery << <<-CONSTRAINT
|
70
|
-
<constraint name="word">
|
71
|
-
<word>
|
72
|
-
<element ns="#{element_namespace unless element_namespace.nil?}" name="#{element}"/>
|
73
|
-
</word>
|
74
|
-
</constraint></options>)
|
75
|
-
CONSTRAINT
|
53
|
+
search_options = setup_options(options, root, root_namespace)
|
54
|
+
search_options.word_constraints["find_by_element"] = {"namespace" => element_namespace, "element" => element}
|
55
|
+
xquery << search_options.to_s
|
56
|
+
xquery << ')'
|
76
57
|
end
|
77
58
|
|
78
|
-
|
79
|
-
|
59
|
+
|
60
|
+
def find_by_attribute(element, attribute, value, root, element_namespace, attribute_namespace, root_namespace, options = nil)
|
80
61
|
xquery = <<-GENERATED
|
81
|
-
import module namespace search = "http://marklogic.com/appservices/search"at "/MarkLogic/appservices/search/search.xqy";
|
82
|
-
search:search("
|
83
|
-
<options xmlns="http://marklogic.com/appservices/search">
|
62
|
+
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
|
63
|
+
search:search("attribute:#{value}",
|
84
64
|
GENERATED
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
xquery << "#{root}</searchable-expression>"
|
91
|
-
end
|
92
|
-
xquery << <<-CONSTRAINT
|
93
|
-
<constraint name="word">
|
94
|
-
<word>
|
95
|
-
<attribute ns="#{attribute_namespace unless attribute_namespace.nil?}" name="#{attribute}"/>
|
96
|
-
<element ns="#{element_namespace unless element_namespace.nil?}" name="#{element}"/>
|
97
|
-
</word>
|
98
|
-
</constraint></options>)
|
99
|
-
CONSTRAINT
|
65
|
+
search_options = setup_options(options, root, root_namespace)
|
66
|
+
attribute_constraint = ActiveDocument::MarkLogicSearchOptions::AttributeConstraint.new(attribute_namespace, attribute, element_namespace, element)
|
67
|
+
search_options.attribute_constraints["attribute"] = attribute_constraint
|
68
|
+
xquery << search_options.to_s
|
69
|
+
xquery << ')'
|
100
70
|
end
|
101
71
|
|
102
72
|
def search(search_text, start, page_length, options)
|
@@ -106,23 +76,36 @@ GENERATED
|
|
106
76
|
option = options.to_s
|
107
77
|
end
|
108
78
|
<<-GENERATED
|
109
|
-
import module namespace search = "http://marklogic.com/appservices/search"at "/MarkLogic/appservices/search/search.xqy";
|
110
|
-
search:search('#{search_text}'
|
79
|
+
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
|
80
|
+
search:search('#{search_text}', #{option}, #{start}, #{page_length})
|
111
81
|
GENERATED
|
112
82
|
end
|
113
83
|
|
114
84
|
def co_occurrence(element1, element1_namespace, element2, element2_namespace, query)
|
115
85
|
<<-GENERATED
|
116
|
-
declare namespace one = "#{element1_namespace}";
|
117
|
-
declare namespace two = "#{element2_namespace}";
|
118
|
-
import module namespace search = "http://marklogic.com/appservices/search"at "/MarkLogic/appservices/search/search.xqy";
|
119
|
-
let $pairs := cts:element-value-co-occurrences(xs:QName('one:#{element1}'), xs:QName('two:#{element2}'), ('frequency-order', 'fragment-frequency','ordered'), cts:query(search:parse('#{query}')))
|
120
|
-
return
|
121
|
-
for $pair in $pairs
|
122
|
-
return
|
123
|
-
|
86
|
+
declare namespace one = "#{element1_namespace}";
|
87
|
+
declare namespace two = "#{element2_namespace}";
|
88
|
+
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
|
89
|
+
let $pairs := cts:element-value-co-occurrences(xs:QName('one:#{element1}'), xs:QName('two:#{element2}'), ('frequency-order', 'fragment-frequency','ordered'), cts:query(search:parse('#{query}')))
|
90
|
+
return
|
91
|
+
for $pair in $pairs
|
92
|
+
return
|
93
|
+
($pair/cts:value[1]/text(),"|",$pair/cts:value[2]/text(),"|",cts:frequency($pair),"*")
|
124
94
|
GENERATED
|
125
95
|
end
|
96
|
+
private
|
97
|
+
|
98
|
+
def setup_options(options, root, root_namespace)
|
99
|
+
if options then
|
100
|
+
search_options = options
|
101
|
+
else
|
102
|
+
search_options = ActiveDocument::MarkLogicSearchOptions.new
|
103
|
+
end
|
104
|
+
if (search_options.searchable_expression.empty?)
|
105
|
+
search_options.searchable_expression[root_namespace] = root unless root.nil?
|
106
|
+
end
|
107
|
+
return search_options
|
108
|
+
end
|
126
109
|
|
127
110
|
end # end class
|
128
111
|
end # end module
|
@@ -13,26 +13,45 @@
|
|
13
13
|
# limitations under the License.
|
14
14
|
|
15
15
|
|
16
|
-
# MarkLogicSearchOptions allow you to control exactly how the ActiveDocument::Finder#search method behaves and what additional
|
17
|
-
# information may be returned in the ActiveDocument::SearchResults object
|
18
|
-
# == Attributes
|
19
|
-
# * return_facets - if true then facet information is returned in the resultant ActiveDocument::SearchResults object. Default is true
|
20
|
-
# * value_constraints - this is a #Hash of value constraint names to their options. e.g. search_options_object.value_constraints["Region"] = {"namespace" => "http://wits.nctc.gov", "element" => "Region"}
|
21
16
|
module ActiveDocument
|
17
|
+
# MarkLogicSearchOptions allow you to control exactly how the ActiveDocument::Finder#search method behaves and what additional
|
18
|
+
# information may be returned in the ActiveDocument::SearchResults object
|
19
|
+
# == Attributes
|
20
|
+
# * return_facets - if true then facet information is returned in the resultant ActiveDocument::SearchResults object. Default is true
|
21
|
+
# * value_constraints - Used for creating searches on the value of an element
|
22
|
+
# this is a #Hash of value constraint names to their options.
|
23
|
+
# e.g. search_options_object.value_constraints["Region"] = {"namespace" => "http://wits.nctc.gov", "element" => "Region"}
|
24
|
+
# * word_constraints - Used for creating searches for a word within an element value. This is a #Hash of word constaint names to their options
|
25
|
+
# this is a #Hash of value constraint names to their options.
|
26
|
+
# e.g. search_options_object.word_constraints["Region"] = {"namespace" => "http://wits.nctc.gov", "element" => "Region"}
|
27
|
+
# * range_constraints - Used for searching for a range of values, also for creating facets or doing co-occurents.
|
28
|
+
# This is a #hash of range_constraint names to their options
|
29
|
+
# e.g. search_options_object.range_constraints["Facility Type"] = {"namespace" => "http://wits.nctc.gov", "element" => "FacilityType", "type" => "xs:string", "collation" => "http://marklogic.com/collation/"}
|
30
|
+
# * directory_constraint - Used for specifying that the search should only executed for this directory, to the depth
|
31
|
+
# specified in directory_depth
|
32
|
+
# * searchable_expression - An expression to be searched. Whatever expression is specified is returned from the search.
|
33
|
+
# This is provided as a hash where the key is the element name and the value is the element's namespace. If there is no
|
34
|
+
# namespace then nil or "" should be passed as the value. eg search_options_object.searchable_expression["element"] = "namespace" or
|
35
|
+
# search_options_object.searchable_expression["element"] = "" if there is no namespace for element
|
22
36
|
class MarkLogicSearchOptions
|
23
|
-
attr_accessor :return_facets, :value_constraints, :word_constraints, :range_constraints
|
37
|
+
attr_accessor :return_facets, :value_constraints, :word_constraints, :attribute_constraints, :range_constraints, :directory_constraint, :directory_depth, :searchable_expression
|
24
38
|
|
25
39
|
def initialize
|
26
40
|
@return_facets = true;
|
27
41
|
@value_constraints = Hash.new
|
28
42
|
@word_constraints = Hash.new
|
43
|
+
@attribute_constraints = Hash.new
|
29
44
|
@range_constraints = Hash.new
|
45
|
+
@searchable_expression = Hash.new
|
46
|
+
@directory_depth = 1
|
30
47
|
end
|
31
48
|
|
32
|
-
|
33
49
|
# outputs the object in correctly formatted XML suitable for use in a search
|
34
50
|
def to_s
|
35
51
|
constraints = String.new
|
52
|
+
additional_query = String.new
|
53
|
+
searchable_path = String.new
|
54
|
+
|
36
55
|
@value_constraints.each do |key, value|
|
37
56
|
constraints << <<-XML
|
38
57
|
<constraint name="#{key.gsub(/\s/, '_')}">
|
@@ -53,6 +72,17 @@ module ActiveDocument
|
|
53
72
|
XML
|
54
73
|
end
|
55
74
|
|
75
|
+
@attribute_constraints.each do |constraint_name, attribute_constraint|
|
76
|
+
constraints << <<-XML
|
77
|
+
<constraint name="#{constraint_name.gsub(/\s/, '_')}">
|
78
|
+
<word>
|
79
|
+
<attribute ns="#{attribute_constraint.attribute_namespace unless attribute_constraint.attribute_namespace.nil?}" name="#{attribute_constraint.attribute}"/>
|
80
|
+
<element ns="#{attribute_constraint.element_namespace unless attribute_constraint.element_namespace.nil?}" name="#{attribute_constraint.element}"/>
|
81
|
+
</word>
|
82
|
+
</constraint>
|
83
|
+
XML
|
84
|
+
end
|
85
|
+
|
56
86
|
@range_constraints.each do |key, value|
|
57
87
|
constraints << <<-XML
|
58
88
|
<constraint name="#{key.gsub(/\s/, '_')}">
|
@@ -75,15 +105,35 @@ module ActiveDocument
|
|
75
105
|
constraints << "</range></constraint>"
|
76
106
|
end
|
77
107
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
108
|
+
# serialize the additional query information
|
109
|
+
if @directory_constraint
|
110
|
+
additional_query = "<additional-query>{cts:directory-query(\"#{directory_constraint}\", \"#{directory_depth}\")}</additional-query>"
|
111
|
+
end
|
112
|
+
|
113
|
+
# serialize the searchable_expression
|
114
|
+
if @searchable_expression.size > 0
|
115
|
+
searchable_path << "<searchable-expression"
|
116
|
+
searchable_path << " xmlns:a=\"#{@searchable_expression.keys[0]}\"" unless @searchable_expression.keys[0].nil? or @searchable_expression.keys[0].empty?
|
117
|
+
searchable_path << '>/'
|
118
|
+
searchable_path << "a:" unless @searchable_expression.keys[0].nil? or @searchable_expression.keys[0].empty?
|
119
|
+
searchable_path << "#{@searchable_expression.values[0]}</searchable-expression>"
|
120
|
+
end
|
121
|
+
|
122
|
+
value = "<options xmlns=\"http://marklogic.com/appservices/search\">"
|
123
|
+
unless additional_query.empty?
|
124
|
+
value << additional_query
|
125
|
+
end
|
82
126
|
|
83
127
|
# add in constraints
|
84
128
|
unless constraints.empty?
|
85
129
|
value << constraints
|
86
130
|
end
|
131
|
+
value << "<return-facets>#{@return_facets}</return-facets>"
|
132
|
+
|
133
|
+
# output the searchable expression
|
134
|
+
unless searchable_path.empty?
|
135
|
+
value << searchable_path
|
136
|
+
end
|
87
137
|
# close the options node
|
88
138
|
value << "</options>"
|
89
139
|
|
@@ -108,6 +158,18 @@ module ActiveDocument
|
|
108
158
|
XML
|
109
159
|
end
|
110
160
|
end
|
161
|
+
|
162
|
+
class AttributeConstraint
|
163
|
+
attr_reader :attribute_namespace, :attribute, :element_namespace, :element
|
164
|
+
|
165
|
+
def initialize (attribute_namespace, attribute, element_namespace, element)
|
166
|
+
@attribute_namespace = attribute_namespace
|
167
|
+
@attribute = attribute
|
168
|
+
@element_namespace = element_namespace
|
169
|
+
@element = element
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
111
173
|
end
|
112
174
|
|
113
175
|
end
|
metadata
CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
version: "0.
|
7
|
+
- 6
|
8
|
+
version: "0.6"
|
9
9
|
platform: ruby
|
10
10
|
authors:
|
11
11
|
- Clark D. Richey, Jr.
|
@@ -13,7 +13,7 @@ autorequire:
|
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
15
|
|
16
|
-
date: 2010-
|
16
|
+
date: 2010-11-03 00:00:00 -04:00
|
17
17
|
default_executable:
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|