Search Query in RavenDB - linq

I would like to know the Search Query for the below condition. I have created an index called MeetingEventIndex as below:
public class MeetingEventIndex : AbstractIndexCreationTask<mngtMeetingEvent>
{
public MeetingEventIndex ()
{
Map = docs => from d in docs select new {d.meetingroomid, d.text, d.details};
Index(x=>x.meetingroomid, FieldIndexing.Analyzed);
Index(x=>x.text, FieldIndexing.Analyzed);
Index(x=>x.details, FieldIndexing.Analyzed);
}
}
I am trying to create a search query as below "Search the term in text or details field and meetingroomid==123"
docsession.Query<mngtMeetingEvent, MeetingEventIndex>()
.Search(x=>x.text , search)
.Search(x=>x.details, search. options: SearchOptions.Or)
.Search(x=>x.meetingroomid, "123", option.SearchOptions.And)
.ToList()
But this is not returning any result.
Basically I am looking for ((searchterm in text field || searchterm in details field ) and mrcode in meetingroomid field).
Please help.

Your query is probably more easily expressed as LuceneQuery, instead:
docsession.Advanced..LuceneQuery<mngtMeetingEvent, MeetingEventIndex>()
.OpenSubClause()
.Search("text", search)
.OrElse()
.Search("details", search)
.CloseSubClause()
.AndAlso()
.WhereEquals("meetingroomid", "123")
.ToList();

Related

ElasticSearch with Nest: Partial search using multiple words using Query<>.Wildcard

I have been pulling my hair out trying to configure and partial search ElasticSearch indexed data using Nest library version 5.3.1 (same version applies to its one of its dependencies; Elasticsearch.Net).
As per suggestions found online I used data attributes to specify analyzer type on some of the indexed properties as shown below:
public class Article
{
public int Id { get; set; }
[Completion(Analyzer = "standard", PreservePositionIncrements = true, PreserveSeparators = true)]
public string Title { get; set; }
public string Url { get; set; }
}
I have at least one record in the search index for type "Article" having title starting with "The greatest ....". Whenever I perform a partial search for a keyword "greatest" using code below, it works just fine returning matching search results.
MultiTermQueryRewrite multiqueryRewrite = null;
var searchQuery = Query<Article>.Wildcard(f => f.Title, "*greatest*", rewrite: multiqueryRewrite);
var client = ElasticsearchClient.GetClient<Article>();
return client.Search<Article>(s => s.Query(searchQuery));
But... if I try searching for "the greatest" keywords with any variation listed below, I don't get any results back.
var searchQuery = Query<Article>.Wildcard(f => f.Title, "*the greatest*", rewrite: multiqueryRewrite);
or
var searchQuery = Query<Article>.Wildcard(f => f.Title, "*the*greatest*", rewrite: multiqueryRewrite);
or even
var searchQuery = Query<Article>.Wildcard(f => f.Title, "*the?greatest*", rewrite: multiqueryRewrite);
I am new to the ElasticSearch product, so any help would be greatly appreciated.
Thanks in advance for your help.
As per documentation
Wild card Matches documents that have fields matching a wildcard expression (not analyzed).
Since title field is Analyzed, it gets tokenized before getting indexed. Some text say The Greatest will get tokenized and then converted into lower case (Behaviour Of Standard Analyzer). So it will be stored in reverse index as two tokens the and greatest.
When you search for *greatest*. It is searched as there is a token corresponding to that.
But when you search for * the greatest * , it is not found as there is no token which contains this text.
You can use Query String
var searchQuery = Query<Article>.QueryString(c => c
.Query("*the greatest*")
.DefaultField(p=>p.Title))
Hope this helps!!
The standard analyzer applied to the Title field produces lower case terms of your "The Greatest" Title in the following format [the, greatest]. You could consider using the Keyword Analyzer but please note you will have to deal with word casing.

java: how to limit score results in mongo

I have this mongo query (java):
TextQuery.queryText(textCriteria).sortByScore().limit(configuration.getSearchResultSize())
which performs a text search and sort by score.
I gave different wiehgt to different fields in the docuemnt, and now I'd like to retrieve only those results with score lower then 10.
is there a way to add that criteria to the query?
this didn't work:
query.addCriteria(Criteria.where("score").lt(10));
if the only way is to use aggregation - I need a mongoTemplate example for that.
in other words
how the do I translate the following mongo shell aggregate command, to java spring's mongoTemplate command??
can't find anywhere how to use the aggregate's match() API with the $text search component (the $text is indexed on several different fields):
db.text.aggregate(
[
{ $match: { $text: { $search: "read" } } },
{ $project: { title: 1, score: { $meta: "textScore" } } },
{ $match: { score: { $lt: 10.0 } } }
]
)
Thanks!
Please check with below code sample, MongoDB search with pagination code in java
BasicDBObject query = new BasicDBObject()
query.put(column_name, new BasicDBObject("$regex", searchString).append("$options", "i"));
DBCursor cursor = dbCollection.find(query);
cursor.skip((pageNum-1)*limit);
cursor.limit(limit);
Write a loop and and call the above code from loop and pass the values like pageNum starts from 1 to n and limit depends on your requirement. check the cursor is empty or not. If empty skip the loop if not continue calling the above code base.
Hope this will be helpful.

elastic4s - control the analyzer to use in term query

I want to control the analyzer in my search query.
At the moment my code looks like this:
client.execute(search in indexName / documentType query {
bool {
must(
termQuery("email", email),
termQuery("name", name)
)
}
}
How can I control the analyzer here?
Note that a term query does not analyze the search terms, so what you're looking for is probably a match query instead and it would go like this:
client.execute(search in indexName / documentType query {
bool {
must(
termQuery("email", email),
matchQuery("name", name) <--- change this to match query
.analyzer(StandardAnalyzer) <--- add this line
)
}
}
The test cases are a good source of information as well. In the SearchDslTest.scala file you'll find how to set all possible properties of a match query.

Query on a nested field using elastic4s on ElasticSearch

I want to query a nested document that is indexed in ES.
For example, the nested field is user which contains two fields id and name. I want to query all documents where the name exactly matches the field user.name.
Cannot figure out how to use the elastic4s DSL for that.
This is how you do nested queries in elastic4s:
First of all, setting up the index such that you have a nested type:
client.execute {
create index "nested" mappings {
"show" as {
"actor" typed NestedType
}
}
}
Then with some sample data
client.execute(
index into "nested/show" fields(
"name" -> "game of thrones",
"actor" -> Seq(
Map("name" -> "peter dinklage", "birthplace" -> "Morristown"),
Map("name" -> "pedro pascal", "birthplace" -> "Santiago")
)
)
)
Then the key part. To search, you used the nested (or in elastic4s 1.4 beta, nestedQuery) to "drop into" the nested scope, where you can search using any standard query type. Here I am just using a simple termQuery search.
client.execute {
search in "nested/show" query nested("actor").query(termQuery("actor.name" -> "dinklage"))
}
How about:
clientProvider.getClient.execute {
(search in path)
.query(
nested("[something].user").query(
bool(must(
term("something.user.name" -> name)
))
)
)
}
Since I'm not familiar with your structure i will provide my own example and maybe you could go from there:
venueData consist of meta data about a venue and the venue itself.
venue got a list of employees that is a NestedType nested()
employee got an id that is of type Long
def venueByEmployeeId(employeeId: Long): Future[Option[VenueData]] = {
clientProvider.getClient.execute {
(search in path)
.query(
nested("venue.employees").query(
bool(must(
term("venue.employees.id" -> employeeId)
))
)
)
}.map(_.getHits.jsonToList[VenueData].headOption)
}
The thing I did forget about the query is that you need to write the entire path term("venue.employees.id" -> employeeId)

Trouble with a LINQ 'filter' code throwing an error

I've got the following code in my Services project, which is trying to grab a list of posts based on the tag ... just like what we have here at SO (without making this a meta.stackoverflow.com question, with all due respect....)
This service code creates a linq query, passes it to the repository and then returns the result. Nothing too complicated. My LINQ filter method is failing with the following error :-
Method 'Boolean
Contains(System.String)' has no
supported translation to SQL.
I'm not sure how i should be changing my linq filter method :( Here's the code...
public IPagedList<Post> GetPosts(string tag, int index, int pageSize)
{
var query = _postRepository.GetPosts()
.WithMostRecent();
if (!string.IsNullOrEmpty(tag))
{
query = from q in query
.WithTag(tag) // <--- HERE'S THE FILTER
select q;
}
return query.ToPagedListOrNull(index, pageSize);
}
and the Filter method...
public static IQueryable<Post> WithTag(this IQueryable<Post> query,
string tag)
{
// 'TagList' (property) is an IList<string>
return from p in query
where p.TagList.Contains(tag)
select p;
}
Any ideas? I'm at a loss :(
Try with Any:
public static IQueryable<Post> WithTag(this IQueryable<Post> query,
string tag)
{
// 'TagList' (property) is an IList<string>
return from p in query
where p.TagList.Any(t => t == tag)
select p;
}
.
UPDATE (by PureKrome)
Another suggestion by Ahmad (in a comment below). This uses the Contains method so it will return all posts that contain the tag 'Test', eg. Post with Tag 'Testicle' :-
public static IQueryable<Post> WithTag(this IQueryable<Post> query,
string tag)
{
// 'TagList' (property) is an IList<string>
return from p in query
where p.TagList.Any(t => t.Contains(tag))
select p;
}
In WithTag try changing the query to use a List rather than an IList:
return from p in query
let taglist = p.TagList as List<string>
where taglist.Contains(tag)
select p;
Also check out this answer, which is similar to my suggestion: Stack overflow in LINQ to SQL and the Contains keyword

Resources