marklogic, howto create range on document properties - node.js

<?xml version="1.0" encoding="UTF-8"?>
<prop:properties xmlns:prop="http://marklogic.com/xdmp/property">
<publicationDate type="string" xmlns="http://marklogic.com/xdmp/json/basic">2015-03-30</publicationDate>
<identifier type="string" xmlns="http://marklogic.com/xdmp/json/basic">2629</identifier>
<posix type="string" xmlns="http://marklogic.com/xdmp/json/basic">nobs</posix>
</prop:properties>
I have a document with these properties above.
I want to filter by "PublicationDate" ...
I tried with "Fields" & "Field Range Indexes" and "Element Range Indexes", but I do not find the syntax (XML or JSON) to designate this property ?
is anyone know this syntax?
kind regards

In addition to the answers that give examples, please keep in mind that the element publicationDate is NOT in the namespace http://marklogic.com/xdmp/property in your example.. So your index configuration should have the namespace for the json/basic as defined per element and references to it as an xs:QName should not refer to "prop:"..
Trying to figure out if your index is correct? You can always try cts:values() from the query console and verify that your index is exactly where you expect it before using it in code.

After many trials, this is what seems to work fine (MarkLogic 8.0-3) :
Without "Field" (where wm is http://marklogic.com/xdmp/json/basic ):
qb.propertiesFragment(qb.value(qb.element(wm,'publicationDate'),'2015-03-30'))
is ok, but the following produces the same error (No element range index ...)
qb.propertiesFragment(qb.range(qb.element(wm,'publicationDate'), '>=' ,'2015-03-01'))
With "Field"
(wm:publicationDate, with wm in Path namespaces, WITHOUT /vm:properties/ before ...) the following seem to work fine :-)))
qb.propertiesFragment(qb.value(qb.field("properties_publicationDate"),'2015-03-30'))
qb.propertiesFragment(qb.range(qb.field("properties_publicationDate"), '>=' ,'2015-03-01'))

I think you are looking for cts:properties-query:
cts:properties-query(
cts:element-range-query(
xs:QName("my:publicationDate"),">",
current-dateTime() - xs:dayTimeDuration("P1D"))))
This example assumes a range index on prop:publicationDate, and also note that this assumes MarkLogic 7 or earlier. In MarkLogic 8, the name of this query appears to have changed to cts:properties-fragment-query.
In node.js, using the query builder, you could achieve something similar:
db.documents.query(
qb.where(
qb.fragmentScope('properties'),
qb.propertiesFragment(
qb.range('publicationDate', '>', ... )
)
)
)

Related

obj.Attributes(0) returns "ID", obj.getAttribute("ID") returns nothing

This is my first attempt to use MSXML2.DOMDocument within VBA, and I'm having a "huh?" moment right off the start. My document looks like this...
<Locations>
<Location ID="23456">
<Properties>
<Property ID="12345">
etc.
I want to make a report with all the Location IDs, so I:
Set locs= XDoc.SelectNodes("//Location")
For Each loc In locs
Debug.Print loc.Attributes(0).Text
Next
and I got 23456. Yay! But of course, those attributes might move around, so let's fix that...
Debug.Print loc.getAttribute("ID").Text
That returns Object required. Looking in the debugger, I can see that loc has one attribute and it's name is ID. That seems right. I can also see that loc.getAttribute("ID") returns null. That seems wrong.
So what's going on here?
I don't know VBA at all but my guess would be that the .attributes[] property returns an attribute object (XmlAttribute?), which would let you access its identifier and value, whereas the getAttribute() function is the getter for the text value of the attribute with that identifier.

Marklogic faceted search and collations

I'm setting up a faceted search in MarkLogic. I have the following range indexes configured:
That is, I have two indexes. The first is on namespace http://www.corbas.co.uk/ns/presentations and local name keyword. The second has the local name level. The collation URI for both is http://marklogic.com/collation/en/S1.
When I try to search using the following I see errors related to collations:
xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search"
at "/MarkLogic/appservices/search/search.xqy";
search:search("levels:Intermediate",
<options xmlns="http://marklogic.com/appservices/search">
<return-results>true</return-results>
<return-facets>true</return-facets>
<constraint name="keywords" facet="true">
<range type="xs:string" collation="http://marklogic.com/collation/en/S1">
<element ns="http://www.corbas.co.uk/ns/presentations" name="keyword"/>
</range>
</constraint>
<constraint name="levels" facet="true">
<range type="xs:string" collation="http://marklogic.com/collation/en/S1">
<element ns="http://www.corbas.co.uk/ns/presentations" name="level"/>
</range>
</constraint>
</options>)
I get the following error:
XDMP-ELEMRIDXNOTFOUND: cts:search(fn:collection(),
cts:element-range query(fn:QName("http://www.corbas.co.uk/ns/presentations","level"),
"=", "Intermediate", ("collation=http://marklogic.com/collation/en/S1"), 1),
("score-logtfidf", "faceted", cts:score-order("descending")),
xs:double("1"), ()) -- No string element range index for
{http://www.corbas.co.uk/ns/presentations}level
collation=http://marklogic.com/collation/en/S1
What am I doing wrong?
Strange Message. If it even got that far, then it looks like your database default collation is changed. Does not answer the question. just strange.
Forst off, I would always add the collation to the constraint:
<search:range type="xs:string" facet="true"
collation="http://marklogic.com/collation/en/S1">
Second, I always troubleshoot range index issue from the query console:
use cts:values() to verify that your indexes are in place and in the namespace and collation you expect. This removes other layers and verifies that the index is as you expect.
And another item: MarkLogic range indexes do not exist until content is indexed. Are you sure you have not turned off auto-index on the database and perhaps content is not indexed? That would give you an error.
To be honest, I would have expected a different error message. I would have expected MarkLogic to complain it couldn't find an index for root collation, because you have not added collation attributes on the range elements in the search options.
Maybe adding those will help.
HTH!
It looks to me like your configuration is correct, which suggests to me that the problem is timing. Once you specify what indexes you want, MarkLogic gets to work creating them. If you run a query that requires those indexes before MarkLogic finishes creating them, you get this error. Depending on the amount of content you have, the creation process can be very quick or take hours.
To check the status, point your browser to the Admin UI (http://localhost:8001) and navigate to the configuration page for your database. Click on the Status tab and look for "Reindexing/Refragmenting State"—if MarkLogic is still reindexing, it will tell you so here and you'll get updates on its progress. (You can also get this information through the Management API.)

Marklogic 8 nodejs queryBuilder.orderBy SEARCH-BADORDERBY

I get this
SEARCH-BADORDERBY: (err:FOER0000) Indexes are required to support element, element-attribute, json-property, or field sort specifications
everytime i try to use the orderBy. I tried in all possible ways.
qb.where(qb.value("hasGeolocation", true)).orderBy("username")
or
qb.where(qb.value("hasGeolocation", true)).orderBy(qb.property("username"))
or
qb.where(qb.value("hasGeolocation", true)).orderBy(qb.sort("username"))
or
qb.where(qb.value("hasGeolocation", true)).orderBy(qb.sort(qb.property("username")))
and for the sort i tried with 'ascending' or 'descending' direction. Nothing works. Am I doing something wrong or is there something wrong with the MarkLogic Node Api?
Victor, it looks to me like you haven't defined a range index on "username". Define a string range index on "username" and I think you'll be set.

ServiceStack OrmLite casing a bug

Doing a simple
db.Dictionary("select Id, Name from \"Product\"");
results in an exception
"column "id" does not exists"
The correct field name is "Id" - seems as if the Postgres in OrmLite does something to the "Id" field. Tried with some random field names with mixed casing and they also ended up in exceptions where the fields where displayed in all lower case.
Can this be achieved somehow or is this an error in OrmLite?
Is this also an issue in db.List, db.Lookup etc?
Have you tried putting the column in quotes to preserve the case?
db.Dictionary("select \"Id\", Name from \"Product\"");
There is a unit test example here https://github.com/ServiceStack/ServiceStack.OrmLite/blob/master/src/ServiceStack.OrmLite.PostgreSQL.Tests/OrmLiteSelectTests.cs#L195

WSO2 - Using get-property() function in Property/Xquery Mediators

Our current service has 7 operations. when writing an outbound xquery "local entry" in wso2, we're trying to retrieve the name of the current operation being executed (how can this be so difficult?).
After reading what i could find in wso2's documentation. it appears as if we need to set up both a Property and an Xquery mediator. supposedly the property mediator would pull the value doing something like get-property('OperationName') and then this would be referenced and passed thru the Xquery mediator.
The other idea was that we needed to define it as a variable in the "Local Registry entry definitions" and than it would be around at all parts of the sequence.
I've tried for 2 days but haven't quite got it.
Please tell me what I'm missing...
Did you try the following xquery sample[1]? I modified the query mediator to get the operation name as follows.
<variable xmlns:ax21="http://services.samples/xsd" xmlns:m0="http://services.samples" name="code" expression="get-property('OperationName')" type="STRING" />
this worked fine. I could see the getQuote in the response message.
[1] http://wso2.org/project/esb/java/4.0.2/docs/samples/advanced_mediation_samples.html#Sample390

Resources