Google Drive Android API 'queryChildren' vs. filter - google-play-services

I wonder if there is a difference between using the following filter construct:
GoogleApiClient GAC;
...
ArrayList<Filter> fltrs = new ArrayList<Filter>();
fltrs.add(Filters.in(SearchableField.PARENTS, (DriveId)id));
...
Query qry = new Query.Builder().addFilter(Filters.and(fltrs)).build();
MetadataBufferResult rslt = Drive.DriveApi.query(GAC, query).await();
as opposed to
DriveFolder dFld = Drive.DriveApi.getFolder(GAC, (DriveId)id)
dFld.queryChildren(GAC, qry).await():
The 'queryChildren' seems redundant.

No, they are functionally equivalent.

Related

What is an alternative for Lucene Query's extractTerms?

In Lucene 4.6.0 there was the method extractTerms that provided the extraction of terms from a query (Query 4.6.0). However, from Lucene 6.2.1, it does no longer exist (Query Lucene 6.2.1). Is there a valid alternative for it?
What I'd need is to parse terms (and corrispondent fields) of a Query built by QueryParser.
Maybe not the best answer but one way is to use the same analyzer and tokenize the query string:
Analyzer anal = new StandardAnalyzer();
TokenStream ts = anal.tokenStream("title", query); // string query
CharTermAttribute termAtt = ts.addAttribute(CharTermAttribute.class);
ts.reset();
while (ts.incrementToken()) {
System.out.println(termAtt.toString());
}
anal.close();
I have temporarely solved my problem with the following code. Smarter alternatives will be well accepted:
QueryParser qp = new QueryParser("title", a);
Query q = qp.parse(query);
Set<Term> termQuerySet = new HashSet<Term>();
Weight w = searcher.createWeight(q, true, 3.4f);
w.extractTerms(termQuerySet);

Creating a MoreLikeThis query yields empty queries and terms

I'm trying to get similar Document of another one . I'm using the Lucene.Net MoreLikeThis-Class to achieve this. For this i seperate my Documents in multiple Fields - Title and Content. Now creating the actual query results in an empty query without interesting Terms.
My could looks like this:
var queries = new List<Query>();
foreach(var docField in docFields)
var similarSearch = new MoreLikeThis(indexReader);
similarSearch.SetFieldNames(docField.fieldName);
similarSearch.Analyzer = new GermanAnalyzer(Version.LUCENE_30, new HashSet<string>(StopWords));
similarSearch.MinDocFreq = 1;
similarSearch.MinTermFreq = 1;
similarSearch.MinWordLen = 1;
similarSearch.Boost = true;
similarSearch.BoostFactor = boostFactor;
using(var reader = new StringReader(docField.Content)){
var searchQuery = similarSearch.Like(reader);
// debugging purpose
var queryString = searchQuery.ToString(); // empty
var terms = similarSearch.RetrieveInterestingTerms(reader); // also empty
queries.Add(searchQuery);
}
var booleanQuery = new BooleanQuery();
foreach(var moreLikeThisQuery in queries)
{
booleanQuery.Add(moreLikeThisQuery, Occur.SHOULD);
}
var topDocs = indexSearcher.Search(booleanQuery, maxNumberOfResults); // and of course no results obtained
So the question is:
Why there are no Terms / why there is no query generated?
I hope important thing's be seen, if not please help me to make my first question better :)
I got it to work.
The problem was, that i worked on the false directory.
I have different Solutions for creating the index and creating the queries and had a missmatch with the index-location.
So the generall solution would be:
Is your Querygenerating-Class fully initialized? (MinDocFreq, MinTermFreq, MinWordLen, has a Analyzer, set the fieldNames)
Is your used IndexReader correctly initialized?

Entity Framework filter data by string sql

I am storing some filter data in my table. Let me make it more clear: I want to store some where clauses and their values in a database and use them when I want to retrieve data from a database.
For example, consider a people table (entity set) and some filters on it in another table:
"age" , "> 70"
"gender" , "= male"
Now when I retrieve data from the people table I want to get these filters to filter my data.
I know I can generate a SQL query as a string and execute that but is there any other better way in EF, LINQ?
One solution is to use Dynamic Linq Library , using this library you can have:
filterTable = //some code to retrive it
var whereClause = string.Join(" AND ", filterTable.Select(x=> x.Left + x.Right));
var result = context.People.Where(whereClause).ToList();
Assuming that filter table has columns Left and Right and you want to join filters by AND.
My suggestion is to include more details in the filter table, for example separate the operators from operands and add a column that determines the join is And or OR and a column that determines the other row which joins this one. You need a tree structure if you want to handle more complex queries like (A and B)Or(C and D).
Another solution is to build expression tree from filter table. Here is a simple example:
var arg = Expression.Parameter(typeof(People));
Expression whereClause;
for(var row in filterTable)
{
Expression rowClause;
var left = Expression.PropertyOrField(arg, row.PropertyName);
//here a type cast is needed for example
//var right = Expression.Constant(int.Parse(row.Right));
var right = Expression.Constant(row.Right, left.Member.MemberType);
switch(row.Operator)
{
case "=":
rowClause = Expression.Equal(left, right);
break;
case ">":
rowClause = Expression.GreaterThan(left, right);
break;
case ">=":
rowClause = Expression.GreaterThanOrEqual(left, right);
break;
}
if(whereClause == null)
{
whereClause = rowClause;
}
else
{
whereClause = Expression.AndAlso(whereClause, rowClause);
}
}
var lambda = Expression.Lambda<Func<People, bool>>(whereClause, arg);
context.People.Where(lambda);
this is very simplified example, you should do many validations type casting and ... in order to make this works for all kind of queries.
This is an interesting question. First off, make sure you're honest with yourself: you are creating a new query language, and this is not a trivial task (however trivial your expressions may seem).
If you're certain you're not underestimating the task, then you'll want to look at LINQ expression trees (reference documentation).
Unfortunately, it's quite a broad subject, I encourage you to learn the basics and ask more specific questions as they come up. Your goal is to interpret your filter expression records (fetched from your table) and create a LINQ expression tree for the predicate that they represent. You can then pass the tree to Where() calls as usual.
Without knowing what your UI looks like here is a simple example of what I was talking about in my comments regarding Serialize.Linq library
public void QuerySerializeDeserialize()
{
var exp = "(User.Age > 7 AND User.FirstName == \"Daniel\") OR User.Age < 10";
var user = Expression.Parameter(typeof (User), "User");
var parsExpression =
System.Linq.Dynamic.DynamicExpression.ParseLambda(new[] {user}, null, exp);
//Convert the Expression to JSON
var query = e.ToJson();
//Deserialize JSON back to expression
var serializer = new ExpressionSerializer(new JsonSerializer());
var dExp = serializer.DeserializeText(query);
using (var context = new AppContext())
{
var set = context.Set<User>().Where((Expression<Func<User, bool>>) dExp);
}
}
You can probably get fancier using reflection and invoking your generic LINQ query based on the types coming in from the expression. This way you can avoid casting the expression like I did at the end of the example.

How to call Oracle's regexp_like function with Nhibernate QueryOver?

I'm aware I need to use Restrictions.Eq and Projections.SqlFunction, but I've been trying for hours without any success (my test app just crashes). Does anyone have an QueryOver example that would do the following in Oracle:
SELECT
*
FROM
V_LOG_ENTRIES
WHERE
regexp_like(ENTRY_TEXT, '(\WPlaced\W)');
UPDATE: Okay, I think part of the problem is that Restrictions.Eq expects an equality, but there is no equality in this case, it's just a function call in the WHERE clause...
The syntax should be like this:
// this is inlined string, but could be concatenated from some params
var sql = #" regexp_like(ENTRY_TEXT, '(\WPlaced\W)') " +
" AS isLike";
var sqlString = new SqlString(sql);
// the ICriterion
var criterion = new NHibernate.Criterion.SQLCriterion(sqlString
, new string[] {}
, new IType[] {}
);
// the query
var query = session.QueryOver<LogEntry>()
.Where(criterion)
...

hibernate - createCriteria or createAlias?

If I want to search those students who take class "Math" and "John" is his group:
shoud I use createCriteria or createAlias?
Criteria:
Criteria criteria = session.createCriteria(Student.class);
Criteria subquery1 = criteria.createCriteria("courses", course).add(Restrictions.eq(course.name, "Math"));
Criteria subquery2 = criteria.createCriteria("group", student).add(Restrictions.eq(student.name, "John"));
how to put subquery1 and subquery2 together with initial criteria?
Alias:
Criteria criteria = session.createCriteria(Student.class).
createAlias("courses", course).add(Restrictions.eq(course.name, "Math")).
createCriteria("group", student).add(Restrictions.eq(student.name, "John"));
When to use createCriteria and when createAlias? I think the boath are the same...
CreateAlias and CreateCriteria are identical in the current versions of Hibernate and NHibernate. The only difference being that CreateCriteria has 2 additional overloads without the alias parameter.
Presumably they were different in a older version, but any differences are long gone.
An alias can be defined in terms of another alias, so your first example can be written as:
// Java
Criteria criteria = session.createCriteria(Student.class)
.createAlias("courses", "course")
.createAlias("course.group", "student")
.add(Restrictions.eq("course.name", "Math"))
.add(Restrictions.eq("student.name", "John"));
// C#
ICriteria criteria = session.CreateCriteria<Student>()
.CreateAlias("Courses", "course")
.CreateAlias("course.Group", "student")
.Add(Restrictions.Eq("course.Name", "Math"))
.Add(Restrictions.Eq("student.Name", "John"));
Adding to xavierzhoa's answer:
There is actually quite a big difference between the two methods which you will notice if you chain Criteria methods. You will continue to work on the original Criteria object when using createAlias, whereas you work on a more nested scope when using createCriteria.
Consider this:
Criteria c = getSession()
.createCriteria(YourEntity.class)
.createCriteria("someMember", "s")
.add(Restrictions.eq("name", someArgument)); // checks YourEntity.someMember.name
versus
Criteria c = getSession()
.createCriteria(YourEntity.class)
.createAlias("someMember", "s")
.add(Restrictions.eq("name", someArgument)); // checks YourEntity.name
However, if you always assign and use an alias you will be able to work around the difference. Like:
Criteria c = getSession()
.createCriteria(YourEntity.class, "y")
.createAlias("someMember", "s")
.add(Restrictions.eq("y.name", someArgument)); // no more confusion
Please refer to the following source code from the Hibernate
public Criteria createCriteria(String associationPath, String alias, int joinType) {
return new Subcriteria( this, associationPath, alias, joinType );
}
public Criteria createAlias(String associationPath, String alias, int joinType) {
new Subcriteria( this, associationPath, alias, joinType );
return this;
}
Criteria criteria = (Criteria)sessionFactory.getCurrentSession().createCriteria(BillEntity.class)
.createAlias("worksEntity", "worksEntity" ,JoinType.LEFT_OUTER_JOIN)
instead of writing (Jointype) use the import file as
(org.hibernate.sql.JoinType..LEFT_OUTER_JOIN)