Why does RavenDB perform an OR operation instead of an AND? - ravendb

Why is there a OR instead of an AND between the SEARCH and the WHERE?
The problem is that the current Lucene query is:
"OrganizationType:Boo ( Name:(Foo) ShortName:(Foo))"
instead of:
"OrganizationType:Boo AND ( Name:(Foo) ShortName:(Foo))"
How can I change that?
RavenQueryStatistics stats;
var organizationQuery = session.Query<Organization>()
.Statistics(out stats)
.Skip((request.Page - 1) * request.PageSize)
.Take(request.PageSize);
if (request.OrganizationType != default(OrganizationType))
{
organizationQuery = organizationQuery.Where(o => o.OrganizationType == request.OrganizationType);
}
if (!string.IsNullOrEmpty(request.Query))
{
organizationQuery = organizationQuery
.Search(c => c.Name, request.Query, escapeQueryOptions: EscapeQueryOptions.AllowPostfixWildcard)
.Search(c => c.ShortName, request.Query, escapeQueryOptions: EscapeQueryOptions.AllowPostfixWildcard);
}
I have added a screenshot with the proposed solution:

To get only documents matching all sub-queries you to have to use Intersect. See the article How to use intersect in the RavenDB documentation.

Because Search is using OR by default. There is an optional parameter that set it to use AND.

Related

Typo3 9.5 - Custom flexform ordering, wrong backquotes in sql

i have an custom extension, where you can select the different entries at the backend, to show them at the list view. I have a custom sorting at my backend, but the system always sort them Descending.
I implemented an "orderBy" function, which doesnt work, because the system uses wrong backspaces.
My code looks like this:
I call the sort function in my "findByUid($uid)" function like this:
$query->setOrderings($this->orderByKey('uid', $uidArray));
protected function orderByKey($key, $uidlist) {
$order = array();
foreach ($uidlist as $uid) {
//$order["$key=$uid"] = \TYPO3\CMS\Extbase\Persistence\QueryInterface::ORDER_DESCENDING;
$order["$key=$uid"] = "ASC";
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($order);
}
return $order;
}
The result at the sql query is:
ORDER BY `tx_MYEXTENSION_domain_model_FIELD`.`uid=3` DESC
But it must be:
ORDER BY `tx_MYEXTENSION_domain_model_FIELD`.`uid` = 3 DESC
Is there a way to change this?
After a lot of search, I found this solution on an stackoverflow entry:
$ids = explode(',',$this->settings['entries'])
foreach($ids as $key => $id){
$entries[$id] = $this->entriesRepository->findByUid($id);
}
This code snippet has to be intergrated at the controller.
For me its working.

NHibernate Linq Expression dynamic projection

How can i dynamically change the selected columns in the generated sql query when using a linq expression?
Its a new session for each time the query is executed.
Even when I set the MapExp as null after first creation an then changing the bool value to false, it still generates the column in the sql query.
The code runs in a wpf application.
System.Linq.Expressions.Expression<Func<Entity, Model>> MapExp = x => new Model
{
Id=xId,
Count= LoadFormulaField ? x.Count: null,
...
};
var result = session.Query<Entity>().Select(MapExp))
Your problem seems to be the ternary-conditional as part of the expression which is causing the "Count" column to always be queried.
One option to avoid this could be:
var query = session.Query<Entity>();
IQueryable<Model> result = null;
if (LoadFormulaField)
{
result = query.Select(x => new Model
{
Id = x.Id,
Count = x.Count,
});
}
else
{
result = query.Select(x => new Model
{
Id = x.Id,
});
}
Which would get a little less ugly if you separate in a couple of methods I think.

Optional term in ContentSearch query

I'm trying to build a lucene query through Sitecore ContentSearch that includes an optional term. The optional term is used to boost certain results. The lucene query should look like this:
+(+(_content:myquery keywords:myquery) boostfield:boostdata)
How can I construct such a query? With PredicateBuilder I can only add And / Or expressions.
Here's an example of how I construct the predicate:
var contentPredicate = PredicateBuilder.Create<MySearchResultItem>(p => p.Content == parameters.QueryString);
contentPredicate = contentPredicate.Or(k => k.Keywords == "myquery");
mainPredicate = mainPredicate.And(contentPredicate);
mainPredicate = mainPredicate.And(f => f["boostfield"] == "boostdata");
This will make "boostfield" a must field wich is not what I need (note the + before the field name):
+(+(_content:myquery keywords:myquery) +boostfield:boostdata)
Is there a way to accomplish this?
Try This:
var contentPredicate = PredicateBuilder.Create<MySearchResultItem>(p => p.Content == parameters.QueryString);
contentPredicate = contentPredicate.Or(k => k.Keywords == "myquery");
mainPredicate = mainPredicate.And(contentPredicate);
var boostQuery = PredicateBuilder.False<MySearchResultItem>();
boostQuery = boostQuery.Or(f => f["boostfield"] == "boostdata");
mainPredicate = mainPredicate.Or(boostQuery)
I think it could get you the results you need.
If you are simply looking to boost results based on an optional field, you can have your predicate builder as follows:
boostfield.contains("term") or field.contains("term")
And then increase the boost value in the standard fields for the field item itself. The order in which you build the predicate has a bearing on the results so make sure you check against the boost field first.

How to select items by providing where clause in pivot

This is my code looks like right now :
$result = Category::with(array(
"getProducts",
"getProducts.getBrand",
"getProducts.getImages",
"getProducts.getDetail",
"getProducts.getTax",
"getProducts.getDiscount",
"getProducts.getAttributes" => function($query) use($_temp){
if($_temp != null){
$query->where_in('attributes.id',$_temp);
}
},
"getSlideshow",
"getSlideshow.getItems",
"getAttributeListing",
"getAttributeListing.getAttributes",
"getAttributeListing.getAttributes.productSpecific"
))
->where('id','=', $category_id)
->first();
Yet, It only filters the getProducts.getAttributes items not the 'getProducts' itself. Is there a way that I can get the Products by attributes?
Note: I am using Laravel 3

Yii CDbCommand create query

I can't create the following query using Yii:
SELECT recipientId as broadcasterId, SUM(quantity) as quantity FROM `creditlog`
WHERE websiteId=3 AND timeAdded>='2013-01-17'
AND timeAdded<='2013-02-17'
AND recipientId IN (10000024, 10000026, 1000028) GROUP BY `recipientId`
I tried:
$command = Yii::app()->db->createCommand();
$command->select('recipientId as broadcasterId, SUM(quantity) as quantity');
$command->from('creditlog');
$command->where('websiteId=:websiteId AND timeAdded>=:dateStart AND timeAdded<=:dateEnd AND recipientId IN (:recipients)',array(':websiteId' => $websiteId, ':dateStart' => $dateStart, ':dateEnd' => $dateEnd, ':recipients' => $broadcasterIds));
$command->group('recipientId');
also the andWhere() function which is in the docs seems to be missing.
The issue is that IN condition but I can't find a way to rewrite it.
Since you don't have access to andWhere, which would make life much simpler, you have to express the parameters with where like this:
$command->where(array(
array('and',
'websiteId=:websiteId',
array('and',
'timeAdded>=:dateStart',
array('and',
// ...
), $parameters);
This is done so that you can at some point use the proper array('in', 'recipientId', $values) syntax to produce the IN(...) SQL.
However, this is ugly and difficult to manage. As long as all the conditions are simply joined together with AND you can construct the data structure programmatically from a saner data representation like this (in effect this is a workaround for the missing andWhere):
$conditions = array(
'websiteId=:websiteId',
'timeAdded>=:dateStart',
'timeAdded<=:dateEnd',
array('in', 'recipientId', $broadcasterIds),
);
$where = null;
foreach ($conditions as $condition) {
if (!$where) {
$where = $condition;
}
else {
$where = array('and', $where, $condition);
}
}
$command->where($where, $parameters);
For more information on why this way of expressing things has to be used you can refer to the documentation for CDbCommand::where.