Xpath search string to cts:search - xpath

I'm trying to use the Xpath string user input in cts:search query to get the matching nodes from the database.
Sample query used :
let $query := "/book/chapter/chapter-meta/meta/meta-value[.='book-title']"
let $results := cts:search($query, cts:and-query(()), (), 0.0)
return $results
The above one is throwing error as XDMP-UNSEARCHABLE, so I tried
let $query := "/book/chapter/chapter-meta/meta/meta-value[.='book-title']"
let $results := cts:search(xdmp:value($query), cts:and-query(()), (), 0.0)
return $results
and this also resulted in the same error.
But when the Xpath is passed directly to cts:search like below ,it is giving results
cts:search(/book/chapter/chapter-meta/meta/meta-value[.='book-title'], cts:and-query(()), (), 0.0)
Could you please suggest how to convert the Xpath string to a proper value for the cts:search to get results like the last query?
Thanks in advance!

Related

Throw Error: XDMP-UNEXPECTED: (err:XPST0003) Unexpected token syntax error, unexpected For_, expecting Order_ or Return_ or Stable_

Once run the below code in qconsole Marklogic, i am getting below error
XDMP-UNEXPECTED: (err:XPST0003) Unexpected token syntax error,
unexpected For_, expecting Order_ or Return_ or Stable_
let $prices := fn:doc('/training/prices.xml')/prices
let $order := fn:doc('/training/order.xml')/order
where $prices/priceList/prod[#num=$order/item/#num]
for $kk in $prices/priceList/prod[#num=$order/item/#num]
return
<item>
{$kk}
</item>
Thanks..
No need for XQuery 3 for this. Just add an extra return between the where and the next for:
let $prices := fn:doc('/training/prices.xml')/prices
let $order := fn:doc('/training/order.xml')/order
where $prices/priceList/prod[#num=$order/item/#num]
return
for $kk in $prices/priceList/prod[#num=$order/item/#num]
return
<item>
{$kk}
</item>
To follow Michael's excellent advice, and optimize to return full items, I'd flip around the XPath, and return order items directly. Something like:
let $prices := fn:doc('/training/prices.xml')/prices
let $order := fn:doc('/training/order.xml')/order
for $item in $order/item
where $prices/priceList/prod[#num = $item/#num]
return
$item
Or even shorter:
let $prices := fn:doc('/training/prices.xml')/prices
let $order := fn:doc('/training/order.xml')/order
return
$order/item[#num = $prices/priceList/prod/#num]
HTH!
In XQuery 1.0, no further for clauses are allowed after a where clause. In Marklogic, you may need to prefix your query string with a 3.0 version declaration:
xquery version "3.0";

Marklogic -How to add the collection name in cts:uris

Query:
let $collection := "sampledata"
for $uri1 in cts:uris((),(),(
cts:element-query(xs:QName("root"),
cts:and-query((
cts:element-attribute-value-query(xs:QName("root"),xs:QName($value1),$value2),
cts:element-attribute-value-query(xs:QName("root"),xs:QName($value3),$value4),
cts:element-value-query(xs:QName("year"),$value5),
cts:element-value-query(xs:QName("month"),$value6),
cts:element-attribute-value-query(xs:QName("num"),xs:QName("value"),$value7)
)))) )
return $uri1
How to add the collection name in above mentioned xquery.
You can use cts:collection-query(), as in:
cts:and-query((
cts:collection-query("sampledata"),
cts:element-query(...)
))
See:
http://docs.marklogic.com/cts:collection-query
By the way, when just returning the uri, there's no need the for/return iteration. The result is the same as just returning cts:uris().
Hoping that helps,

How to skip a row with file exists condition in laravel

This is for a search query based on many input fields, i'm doing if statements inside the query based on the inputs, for example :
$query = Model::all();
if($field = Input::get('field'))
$query->where('column_name', $field);
but what i want to do also is a condition to skip a row if there is no image with a name of that row id, like so :
if( file_exists('/img/'.$this_query->id) )
$query->skip();
Option 1: would be to make an array of the filenames, then utilize the whereIn query builder method, which checks for the occurrence of a column value in an array.
$query = Model::query();
$filenames = scandir('/img');
// the following excludes any id's not in the $filenames array
$query = $query->whereIn('id', $filenames);
Option 2: Run the query and then filter the resulting Collection in Laravel.
$query = Model::query();
// ... then build up your query
// the following gets the query results and then filters them out
$collection = $query->get()->filter( function($item) {
return file_exists('/img/'.$item->id);
}
Rationale: the database cannot check the filesystem during it's processing; so you either need to (Option 1) provide it a list from which to check, or (Option 2) do the checking after you get() the results back from the query.

Laravel 4 query giving error

I have this query in laravel which runs perfectly fine when it finds the data in table but give error when it doesn't find the matched data, how can make query to give no error when it doesn't find data in table ?
DB::select(DB::raw('SELECT * FROM time
WHERE p_day = dayname(CURDATE())
AND CURTIME() BETWEEN p_start AND p_end'))[0];
thats because then there is no item in the array returned by DB::select. You would have to check its lenght before accessing it using index operator
try sth. like that:
$results = DB::select(DB::raw('SELECT * FROM time
WHERE p_day = dayname(CURDATE())
AND CURTIME() BETWEEN p_start AND p_end'));
if (!empty($results)) // or: if (count($results) > 0)
{
// Stuff was returned
$desiredResult = $results[0];
// Your hork here
}
else
{
// what you need to to if nothing is returned (no matches for your query)...
}

Code Igniter - remove single quotes from where_in

I have 2 queries:
$genres = $this->db->select('Group_Concat(intGenreId) strDJGenres')
->from('tblDJGenres')
->where('intDJId', $this->session->userdata('non_admin_userid'))
->get()
->row();
$results = $this->db->select('tblTracks.*, tblGenres.strName as strGenreName')
->from('tblTracks')
->join('tblGenres', 'tblTracks.intGenreId = tblGenres.intGenreId', 'left')
->where_in('tblTracks.intGenreId', $genres->strDJGenres)
->get()
->result();
The first query is returning a string such as
'1,2,3,4,8,6,5,7,45,66'
which I am using in my where_in clause on the second query. The issue is that with this string, it is writing the SQL like:
SELECT `tblTracks`.*, `tblGenres`.`strName` as strGenreName FROM (`tblTracks`) LEFT JOIN `tblGenres` ON `tblTracks`.`intGenreId` = `tblGenres`.`intGenreId` WHERE `tblTracks`.`intGenreId` IN ('1,2,3,4,8,6,5,7,45,66')
With the quote around it, it is treated as a single value. How can I get the second query to perform how I want it? ie
.... where `tblTracks`.`intGenreId` IN (1,2,3,4,8,6,5,7,45,66)
Multiple values can be passed to the where_in clause as an array.
The quotes from the start and end of the string can be removed using trim():
$dj_genres = trim($genres->strDJGenres, "'");
This string can then be converted into an array of strings, to pass to the where_in clause of the second query.
$dj_genres_array = explode(",", $dj_genres);
Or, if you need an array of integers:
$dj_genres_int_array = array_map('intval', $dj_genres_array);
You can just add the resultant array into the second query:
// ...
->where_in('tblTracks.intGenreId', $dj_genres_array)
// ...
Or:
// ...
->where_in('tblTracks.intGenreId', $dj_genres_int_array)
// ...
Answer given by the JLeft :
The quotes from the start and end of the string can be removed using the following function:
$dj_genres = trim($genres->strDJGenres, "'");
This string can then be converted into a array of strings, to pass to the where_in clause of the second query.
$dj_genres_array = explode(",", $dj_genres);
If you need an array on integers, it can be generated as so:
$dj_genres_int_array = array_map('intval', $dj_genres_array);
was working absolutely fine...Thanks JLeft

Resources