How to restrict Search API for particular collection search in Marklogic? - xquery

import module namespace search = "http://marklogic.com/appservices/search"
at "/MarkLogic/appservices/search/search.xqy";
let $options :=
<options xmlns="http://marklogic.com/appservices/search">
<constraint>
<collection>'/mycollection'</collection>
</constraint>
</options>
let $options-1 :=
<options xmlns="http://marklogic.com/appservices/search">
<constraint name="collection">
<collection prefix="/mycollection"/>
</constraint>
</options>
return
search:search('Text',$options)
I tried both the options, but none of this is restricting the search to the particular collection /mycollection.

You have defined a constraint called collection and have configured the prefix for that constraint to be /mycollection, however you have not applied that constraint to your search.
The constraints are not automatically applied to your searches, they just define what search terms and options can be applied.
If you look at the Collection Constraint Example they note:
If you include a prefix attribute in the definition of a collection constraint, then the collection name is derived from the prefix concatenated with the constraint value.
So, in order for you to apply the constraint that limits to the collection /mycollection I would do this:
xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search"
at "/MarkLogic/appservices/search/search.xqy";
let $options :=
<options xmlns="http://marklogic.com/appservices/search">
<constraint name="collection">
<collection />
</constraint>
</options>
return
search:search("collection:/mycollection " ||'Text', $options)
If all of your collections start with a leading slash, you could set that as the prefix and then just apply the "name" of the collection without the leading slash:
xquery version "1.0-ml";
import module namespace search = "http://marklogic.com/appservices/search"
at "/MarkLogic/appservices/search/search.xqy";
let $options :=
<options xmlns="http://marklogic.com/appservices/search">
<constraint name="collection">
<collection prefix="/"/>
</constraint>
</options>
return
search:search("collection:mycollection "||'Text', $options)

Related

How to generate relationship without ArrayCollection type (with Doctrine)

I want generate my entities without the dependency Doctrine\Orm\PersistentCollection.
All fields of my entity are mapped in Entity.orm.xml
I would like change the type of the return relationship (ArrayCollection to simple array)
Team.orm.xml :
<doctrine-mapping>
<entity name="App\Entity\Team" table="team" repository-class="App\Repository\TeamRepository">
<id name="id" column="id" type="integer">
<generator strategy="AUTO"/>
</id>
<field name="name" type="string"/>
<many-to-many field="users" target-entity="User"/>
</entity>
</doctrine-mapping>
My property users (isn't in __construct function):
/** #var array<int, User[]> $users */
private array $users;
I would be happy to receive any ideas or propositions in order to develop our reflections on this issue. Thanks !

Symfony 3: doctrine:generate:entities ignoring property type for default value

I'm having trouble with the Doctrine entities generator used on Symfony 3 project with XML ORM definitions file rather than entities annotations.
When specifying the default value for field like on the examples below:
<field name="isDeleted" column="is_deleted" type="boolean">
<options>
<option name="default">false</option>
</options>
</field>
<field name="priority" column="priority" type="integer">
<options>
<option name="default">0</option>
</options>
</field>
results in generated entity that it has the default values for properties assigned as a string rather than proper integer or boolean value specified in the configuration.
The entity properties looks like the following:
/**
* #var boolean
*/
private $isDeleted = 'false';
/**
* #var integer
*/
private $priority = '0';
What am I doing wrong? How to fix it?
Thanks for any help and ideas.

How to do a multiple term search within an element

I am attempting to do a search which checks that each word within a query string is contained within a specific element. For example, if the $query = "Sports With Stripes" then the specific element must contain all three words (In any order, so it is not a phrase).
To restrict the search to the element I have the following constraint:
<constraint name="inelement">
<word>
<element ns="" name="myElement"/>
<term-option>case-insensitive</term-option>
</word>
</constraint>
This seems okay, but I am struggling when it comes to what do put in the search:search. I first attempted this:
search:search('inelement:spots with stripes', $options, 1, 25)
This did not work as it just restricts "spots" to my element.
I then tried the following, which does get me the results I need but I was wondering if this is the only way to achieve this or if there is another way such as using an operator in-between my search terms.
search:search('inelement:spots inelement:with inelement:stripes', $options, 1, 25)
Is there a better way? Or do I manually have to parse my queryString to separate them in to individual words before adding the constraint to my search:search?
To apply a constraint across whitespace, use quotes.
inelement:"spots with stripes"
With the default parser that will return a single element-word term. To break the term into words, you could write a custom parser function. There is an example at http://docs.marklogic.com/guide/search-dev/search-api#id_49750
You may want a cts:near-query to ensure that all three words are in the same element. And you may need to enable element-word-positions in the database configuration.
Instead of search:search you can use a combination of search:parse and search:resolve and do your own custom processing in between. If you want to always search within a specific element, you can update the query in between those steps.
declare function local:word-to-element-query(
$element as xs:QName,
$query as item()
) as item()
{
typeswitch ($query)
case element(cts:word-query)
return cts:element-word-query($element,
$query/cts:text/string(),
$query/cts:option/string())
case text() return $query
default return
element { node-name($query) } {
$query/#*, local:word-to-element-query($element, $query/node())
}
};
let $query :=
local:word-to-element-query(
xs:QName('myElement'),
search:parse('spots with stripes'))
return search:resolve($query)
The recursive typeswitch template is a good strategy for modifying the default parse output and adding other custom logic.

XQuery to change attribute value and return previous one

I'm trying to update an attribute value of a node and return its previous value all in one query and I can't find a way to do it. I'm using BaseX as my XML/XQuery database.
For now I've tried doing this:
/Root/Elem/properties/property[#id='17']/#format,
replace value of node /Root/Elem/properties/property[#id='17']/#format with 'URL'
and also this:
for $prop in /Root/Elem/properties/property[#id='17']
let $format := $prop/#format
return (replace value of node $prop/#format with 'URL', $format)
And multiple other tests but they all lead to the following error:
List expression: no updating expression allowed.
Is it a limitation of BaseX or is it not possible in XQuery?
XQuery Update does not allow returning results from an updating query. You can however use BaseX's proprietary update:output($seq) function to do that:
for $prop in /Root/Elem/properties/property[#id='17']
let $format := $prop/#format
return (replace value of node $format with 'URL', update:output($format))

Doctrine2 returns returns fields with wrong data type

I'm working on a mid-size Symfony2 project. While using several doctrine entities I stucked on the following "error".
I've got an entity with 3 fields:
<entity name="xxx\yyyBundle\Entity\ABTexte" table="ABTexte">
<id name="Nr" type="integer" />
<field name="OID" type="integer" />
<field name="Text" type="string" />
<many-to-one target-entity="xxx\yyyBundle\Entity\ABKopf" field="ABKopf" inversed-by="ABTexte">
<join-column name="OID" referenced-column-name="OID" on-delete="CASCADE" />
</many-to-one>
</entity>
After loading one or more entities using $repo->findBy() I receive an entities with wrong datatypes. My result is:
$ABKopf->Nr (int)
$ABKopf->Text (string)
$ABKopf->OID (string) <===== !!!!!!!!!
It's very important for my application to get this value as an integer. Do you have any ideas what causes this behaviour?
PS: All values are filled with data of the correct data type. e. g. OID = 999000
I verified that, when I use an integer column as a foreign key (many-to-one relationship...) doctrine always returns it as a string
Relationship in ABKopf:
<entity name="xxx\yyyBundle\Entity\ABKopf" table="ABKopf">
<id name="OID" column="OID" type="integer" />
<field name="ABNr" column="ABNr" type="integer" />
<!-- ... -->
<one-to-many target-entity="xxx\yyyBundle\Entity\ABTexte" field="ABTexte" mapped-by="ABKopf" />
</entity>
ABTexte-Entity: https://gist.github.com/715f3881a57cdd8a7d23
Based on your comment
PS: At first I didn't define a datatype for column OID so it was a
varchar(255) / string. Later I changed the datatype to integer, and
used doctrine:generate:schema command to update the column in the
database...
I'll explain you the entire "doctrine process" for generate entities.
At first you write a PHP class with some annotation or a yml,xml,ecc that tells doctrine how to create entities, link each other, and so on.
Second step is about generating getters and setter in an automated way doctrine:generate:entities
IMPORTANT
The third step is, when you want to change something about your schema, use the following command doctrine:schema:update --force
END IMPORTANT
I suppose that doctrine:generate:schema doesn't do what you're expecting that it to do.
Try with command that I've wrote on the third step

Resources