elastic4s - control the analyzer to use in term query - elasticsearch

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.

Related

How can I do a WpGraphQL query with a where clause?

This works fine
query QryTopics {
topics {
nodes {
name
topicId
count
}
}
}
But I want a filtered result. I'm new to graphql but I see a param on this collection called 'where', after 'first', 'last', 'after' etc... How can I use that? Its type is 'RootTopicsTermArgs' which is likely something autogenerated from my schema. It has fields, one of which is 'childless' of Boolean. What I'm trying to do, is return only topics (a custom taxonomy in Wordpress) which have posts tagged with them. Basically it prevents me from doing this on the client.
data.data.topics.nodes.filter(n => n.count !== null)
Can anyone direct me to a good example of using where args with a collection? I have tried every permutation of syntax I could think of. Inlcuding
topics(where:childless:true)
topics(where: childless: 'true')
topics(where: new RootTopicsTermArgs())
etc...
Obviously those are all wrong.
If a custom taxonomy, such as Topics, is registered to "show_in_graphql" and is part of your Schema you can query using arguments like so:
query Topics {
topics(where: {childless: true}) {
edges {
node {
id
name
}
}
}
}
Additionally, you could use a static query combined with variables, like so:
query Topics($where:RootTopicsTermArgs!) {
topics(where:$where) {
edges {
node {
id
name
}
}
}
}
$variables = {
"where": {
"childless": true
}
};
One thing I would recommend is using a GraphiQL IDE, such as https://github.com/skevy/graphiql-app, which will help with validating your queries by providing hints as you type, and visual indicators of invalid queries.
You can see an example of using arguments to query terms here: https://playground.wpgraphql.com/#/connections-and-arguments

ElasticSearch - creating exceptions for fuzzy terms

I have simple elastic query that does a simple text field search with the fuziness distance of one:
GET /jobs/_search
{
"query": {
"fuzzy": {
"attributes.title": {
"value": "C#"
"fuzziness": 1
}
}
}
}
The above query does exactly what it is told to do, but I have a cases where I don't want a word to resolve (with fuzziness) to another specific word. In this case, I don't want C# to also return C++ results. Similarly I don't want cat to return car results.
However I do still need the fuzziness option if someone did actually misspelled cat. In that case it can return results of both cat and car.
I think this is possible with some bool query combination, it should be something like this:
bool:
//should
//match query without fuzzy
//bool
//must
//must with fuzzy query
//must_not with match query

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.

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)

Search Query in RavenDB

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();

Resources