Raven query returns 0 results for collection contains - ravendb

I have a basic schema
Post {
Labels: [
{ Text: "Mine" }
{ Text: "Incomplete" }
]
}
And I am querying raven, to ask for all posts with BOTH "Mine" and "Incomplete" labels.
queryable.Where(candidate => candidate.Labels.Any(label => label.Text == "Mine"))
.Where(candidate => candidate.Labels.Any(label => label.Text == "Incomplete"));
This results in a raven query (from Raven server console)
Query: (Labels,Text:Incomplete) AND (Labels,Text:Mine)
Time: 3 ms
Index: Temp/XWrlnFBeq8ENRd2SCCVqUQ==
Results: 0 returned out of 0 total.
Why is this? If I query for JUST containing "Incomplete", I get 1 result.
If I query for JUST containing "Mine", I get the same result - so WHY where I query for them both, I get 0 results?
EDIT:
Ok - so I got a little further. The 'automatically generated index' looks like this
from doc in docs.FeedAnnouncements
from docLabelsItem in ((IEnumerable<dynamic>)doc.Labels).DefaultIfEmpty()
select new { CreationDate = doc.CreationDate, Labels_Text = docLabelsItem.Text }
So, I THINK the query was basically testing the SAME label for 2 different values. Bad.
I changed it to this:
from doc in docs.FeedAnnouncements
from docLabelsItem1 in ((IEnumerable<dynamic>)doc.Labels).DefaultIfEmpty()
from docLabelsItem2 in ((IEnumerable<dynamic>)doc.Labels).DefaultIfEmpty()
select new { CreationDate = doc.CreationDate, Labels1_Text = docLabelsItem1.Text, Labels2_Text = docLabelsItem2.Text }
Now my query (in Raven Studio) Labels1_Text:Mine AND Labels2_Text:Incomplete WORKS!
But, how do I address these phantom fields (Labels1_Text and Labels2_Text) when querying from Linq?

Adam,
You got the reason right. The default index would generate 2 index entries, and your query is executing on a single index entry.
What you want is to either use intersection, or create your own index like this:
from doc in docs.FeedAnnouncements
select new { Labels_Text = doc.Labels.Select(x=>x.Text)}
And that would give you all the label's text in a single index entry, which you can execute a query on.

Related

Not able to put tag column value on monday item

I am trying to use python to automation common Monday tasks. I am able to create an item in the board but the column (type=tag) is not updating.
I used this tutorial:
https://support.monday.com/hc/en-us/articles/360013483119-API-Quickstart-Tutorial-Python#
Here is my graphql code that I am executing:
query = 'mutation ($device: String!, $columnVals: JSON!) { create_item (board_id:<myboardid>, item_name:$device, column_values:$columnVals) { id } }'
vars = {'device': device,
'columnVals': json.dumps({
'cloud_name6': {'text': cloudname} # this is where i want to add a tag. cloud_name6 is id of the column.
})
}
data = {'query' : query, 'variables' : vars}
r = requests.post(url=apiUrl, json=data, headers=headers) print(r.json())
I have tried changing id to title as key in the Json string but no luck. I fetched the existing item and tried to add exact json string but still no luck. I also tried below json data without any luck
'columnVals': json.dumps({
'cloud_name6': cloudname
})
Any idea what's wrong with the query?
When creating or mutating tag columns via item queries, you need to send an array of ids of the tags ("tag_ids") that are relating to this item. You don't set or alter tag names via an item query.
Corrected Code
'columnVals': json.dumps({
'cloud_name6': {'tag_ids': [295026,295064]}
})
https://developer.monday.com/api-reference/docs/tags

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.

Grails: "where" query with optional associations

I'm trying to run a "where" query to find a domain model object that has no association with another domain model object or if it does, that domain model object has a specific property value. Here's my code:
query = Model.where({
other == null || other.something == value
})
def list = query.list()
However, the resulting list only contains objects that match the second part of the OR statement. It contains no results that match the "other == null" part. My guess is that since it's checking a value in the associated object its forcing it to only check entries that actually have this associated object. If that is the case, how do I go about creating this query and actually having it work correctly?
You have to use a LEFT JOIN in order to look for null associations. By default Grails uses inner join which will not be joined for null results. Using withCriteria as below you should get the expected results:
import org.hibernate.criterion.CriteriaSpecification
def results = Model.withCriteria {
other(CriteriaSpecification.LEFT_JOIN){
or{
isNull 'id'
eq 'something', value
}
}
}
UPDATE
I know aliasing is not possible in DetachedCritieria where one would try to specify the join as in createCriteria/withCriteria. There is an existing defect regarding adding the functionality to DetachedCriteria. Just adding the work around for where query as mentioned in defect.
Model.where {
other {
id == null || something == value
}
}.withPopulatedQuery(null, null){ query ->
query.#criteria.subcriteriaList[0].joinType = CriteriaSpecification.LEFT_JOIN
query.list()
}
I would rather use withCriteria instead of the above hack.
this might work:
query = Model.where({
isNull( other ) || other.something == value
})
If that wouldn't work, try something like:
other.id == null || other.something == value
UPDATE:
or with good'ol criteria query:
list = Pack.withCriteria{
or{
isNull 'other'
other{ eq 'something', value }
}
}

Getting greater count result in raven index statistics

I have an index, with a transformation:
docs.FeedPosts
.SelectMany(doc => (doc.Labels).DefaultIfEmpty(), (doc, docLabelsItem1) => new {AnnouncementGuid = doc.AnnouncementGuid, CreationDateUtc = doc.CreationWhenAndWhere.Time, FeedOwner = doc.FeedOwner, Key = doc.Key, Labels_Text = doc.Labels
.Select(label => label.Text), SequentialId = ((long)doc.SequentialId), SubjectGuid = doc.SubjectGuid, SubjectId = doc.SubjectId})
(transform)
results
.Select(doc => new {doc = doc, tags = Database.Load(doc.Key)})
.Select(__h__TransparentIdentifier1 => new {AnnouncementGuid = __h__TransparentIdentifier1.tags.AnnouncementGuid, AreCommentsLocked = __h__TransparentIdentifier1.tags.AreCommentsLocked, Author = __h__TransparentIdentifier1.tags.Author, Comments = __h__TransparentIdentifier1.tags.Comments, CreationWhenAndWhere = __h__TransparentIdentifier1.tags.CreationWhenAndWhere, FeedOwner = __h__TransparentIdentifier1.tags.FeedOwner, Key = __h__TransparentIdentifier1.tags.Key, Labels = __h__TransparentIdentifier1.tags.Labels, MessageBody = __h__TransparentIdentifier1.tags.MessageBody, SequentialId = __h__TransparentIdentifier1.tags.SequentialId, SubjectGuid = __h__TransparentIdentifier1.tags.SubjectGuid, SubjectId = __h__TransparentIdentifier1.tags.SubjectId})
Which works for QUERYING the data. But if I then request statistics, I get back the wrong document count! (I Limit the query to 0 results, and request raven statistics).
It seem that because my document looks like this:
{
Labels: [
{ Text: "label 1" }
{ Text: "label 2" }
]
}
Raven generates TWO index entries for this one document - If I look in the raven query tool, the first index contains the actual index data, the second index document is just completely empty.
If I have 3 labels in a document, it generates 3 index results... and my 'count' is 3 times what it should be.
Whats going on?
Thanks
I translated your index to the query syntax, because that is easier to look at:
from doc in docs.FeedPosts
from NOT_USING_THIS in doc.labels
select new
{
AnnouncementGuid = doc.AnnouncementGuid,
CreationDateUtc = doc.CreationWhenAndWhere.Time,
FeedOwner = doc.FeedOwner,
Key = doc.Key,
Labels_Text = doc.Labels.Select(label => label.Text),
SequentialId = ((long)doc.SequentialId),
SubjectGuid = doc.SubjectGuid,
SubjectId = doc.SubjectId}
}
The second from clause is the SelectMany() in your index, whose value you are not using
If you'll remove that and work on top of the root object, you won't have this issue.
The docs for this are:
http://ravendb.net/docs/faq/skipped-results

How to get count of all items in a criteria GORM query

So i have this criteria query that is getting 10 feature articles that have itemchannel objects that are of type 4 and in a channel of id 1 i.e get me top 10 articles which are of type feature and in channel x.
def criteria = Feature.createCriteria()
list = criteria.list {
maxResults(params.max)
itemChannels {
eq ('itemType.id',(long)4)
eq ('channel.id',(long)1)
}
}
How do i get the total count efficiently i.e. i have the articles for page 1 but i need the total number for pagination?
Thanks
Think i sorted this.
criteria = Feature.createCriteria()
count = criteria.get{
projections {
countDistinct('id')
}
itemChannels {
eq ('itemType.id',(long)4)
eq ('channel.id',(long)2)
}
}