search multiple field as regexp query in elasticsearch - node.js

I am trying to search by different fields such as title and description. When i type keywords, elasticseach must found something if description or title includes that i typed keywords. This is my goal. How can i reach my goal?
You can see the sample code that i used for one field.
query: {
regexp: {
title: `.*${q}.*`,
},
},
I also tried below one but it gave syntax error.
query: {
regexp: {
title: `.*${q}.*`,
},
regexp: {
description: `.*${q}.*`,
},
},

To do so, you need to use a bool query.
GET /<you index>/_search
{
"query": {
"bool": {
"should": [
{
"regexp": {
"title": ".*${q}.*"
}
},
{
"regexp": {
"description": ".*${q}.*"
}
}
]
}
}
}
You can find the documentation => [doc]

Related

Conditionally adding term and multi_match filters to elasticsearch with nodejs client

I am using ElasticSearch 7.9 with a nodejs client. I have the following query :
{
"query": {
"bool": {
"must":[
{ "terms" : { "id" : ["5f0d06fb5112231eb89eb819", "5f0d06fb5112231eb89eb817"] } },
{"query_string": {
"query": "(News) OR (Entertainent)",
"fields": [ "topics", "subTopics", "categories"]
}
},
{
"multi_match": {
"query": "publisher",
"fields": ["text", "name", "title", "subtitle", "description"]
}
}
]
}
}
}
I want to be able to conditionally add the terms filter for id if list of ids coming in to the nodejs/js function is not empty. Similarly for the multi_match query text as well. Add the multi_filter only if the incoming text is not empty
Should all queries be pre-constructed or is it possible to have conditional blocks and add only if the empty text or array of Ids are not empty.
My current method expects both ids and text input to the method to have valid values but these could be empty. Do I separate methods to handle the empty conditions
export const searchResults = async (text, ids) => {
const response = await client.search({
index: "new_index", //customer.id
type: "_doc",
body: {
query: {
bool: {
must: [
{terms: {"id": ids}},
{query_string: {
query: "(News) OR (Entertainent)",
fields: [ "topics", "subTopics", "categories"]
}
},
{
multi_match: {
query: text,
fields: ["text", "name", "title", "subtitle", "description"],
}
}
],
}
}
},
});
return response?.hits?.hits.map(({_source}) => _source) || [];
};
any help is really appreciated.
In a production environment and managing client based applications you should use search-templates, where you can use conditional blocks of queries. Besides, if you would want to change your query you would not neet to redeploy your app, just change it on ES.

node elastic search strict match

can anyone tell me how to strict match in elasticsearch-js. here is my search
client.search({{
index: 'hash_tag',
type: 'hash_tag',
lenient:false,
body: {
query: {
match: {
tag_name: 'hash tag 1'
}
}
}
}).then(function (body) {
console.log("body", JSON.stringify(body));
}, function (error) {
console.trace(error.message);
})
this query search either hash, tag ,1 i'm looking for exact whole string match.here is my example index style.
{
"_index": "hash_tag",
"_type": "hash_tag",
"_id": "3483",
"_score": 0.019691018,
"_source": {
"id": "3483",
"labels": [
"hash_tag"
],
"tag_name": "hash tag 2"
}
}
by default elasticsearch will "tokenize" your text fields to add them to the inverted index, that's why you get results for each term used.
In order to get the full match you can have different approaches, the simplest would be to use a match_frase:
GET /megacorp/employee/_search
{
"query" : {
"match_phrase" : {
"about" : "rock climbing"
}
}
}
Another option would be to add that specific field with a mapping of not_analyzed, then the text wouldn't be tokenized.

search query in elasticsearch

I have documents like the below in my elasticsearch
{"method":"POST","url":"/saas/services/1.0/account/*/purchase/*/subscription/cancel"}
{"method":"POST","url":"/saas/services/1.0/account/*/purchase/*/cancel"}
I am searching these documents using node.js client. Below is the query I am sending.
Example 1 type : DSL
client.search({
index: 'my_node',
body: {
query: {
bool: {
must: {
match: { method: 'POST' },
match: { url: '/saas/services/1.0/account/*/purchase/*/cancel' }
}
}
}
}
}
Output
I am getting the other record with subscription cancel. The query is not matching the exact document. I tried the below query , it worked for this case but not working for few other test cases.
document
{"method":"POST","url":"/paas/service/1.0/act/*/purchase"}}
{"method":"GET","url":"/paas/service/1.0/act/*/purchase"}}
{"method":"PUT","url":"/paas/service/1.0/act/*/purchase"}}
Example 2 type : query string
client.search({
index: 'my_node',
q: 'method: POST AND url: /saas/services/1.0/account/*/purchase'
}
Output
I get the GET purchase document regardless of other two. Tried for few other documents, the method argument is not getting recognized.
How do I write elasticsearch query to search through the documents to match both the properties of method and url. i had tried query time boosting for the url but doesn't seem to work.
Edit - Mapping information
{
"nodeclient": {
"mappings": {
"logs": {
"properties": {
"method": {
"type": "string" },
"url": {
"type": "string" }
} } }
}
}
Try add quotation marks
client.search({ index: 'my_node', body: { "query": { "bool": { "must": {
"match": { "method": 'POST' }, "match": { "url":
'/saas/services/1.0/account//purchase//cancel' } } } } } }
I tried optimizing the query with Mirage plugin for elasticsearch queries. I was trying with different examples and saw the responses. Below is my final query that works for my scenario
{
"query": {
"bool": {
"must": [
{ "match_phrase": { "url": uri }},
{ "match": { "method": http } }
]}
}
match_phrase suited better for the url parameter. Also I missed the array part inside the must clause.

mongoosastic search with two fields with and condition

I have a chatting applications developed in Angular js, Node.js, MongoDB with elastic search integration. I had provided search functionality for chats, which user can enter any combination. Options are chat message, user and date.
So i want to search in elastic search db with help of nodejs, with mutiple field combination. For example, 1) search with username='mohan' and the date='anydate', 2) username='mohan' and chatmessage='Hi there'.
So the result should come which satisfy both conditions.
How can we achieve this using mongoosastic? I tried with below query. But it is giving result with OR condition, I want with AND condition.
{
"query": {
"bool": {
"should": [{
"match": {
"feedMsg": "Hi there"
}
}, {
"match": {
"userId": 'mohan'
}
}, {
"range": {
"feedTime": {
"from": '27/10/2016',
"to": '27/10/2016'
}
}
}]
}
}
}
I found the solutions. Bool Query with must is working for me.
{
"bool" : {
"must" : [],
"should" : [],
"must_not" : [],
"filter": []
}
}
must- All of these clauses must match. The equivalent of AND.
must_not - All of these clauses must not match. The equivalent of
NOT.
should - At least one of these clauses must match. The equivalent of OR.
filter - Clauses that must match, but are run in non-scoring,
filtering mode.
You should use this format, it really works...
var query = {
query_string: {
filtered: {
query: {
multi_match: {
query: req.query.q, // or anything you will put here
}
},
filter: {
term: {
'field': value
}
}
}
}
}

ElasticSearch MultiField Search Query

I have an endpoint that I am proxying into ElasticSearch API for a simple user search I am conducting.
/users?nickname=myUsername&email=myemail#gmail.com&name=John+Smith
Somet details about these parameters are the following
All parameters are optional
nickname can be searched as a full text search (i.e. 'myUser' would return 'myUsername')
email must be an exact match
name can be searched as full text search for each token (i.e. 'john' would return 'John Smith')
The ElasticSearch search call should treat the parameters collectively as AND'd.
Right now, I am not truly sure where to start as I am able to execute the query on each of the parameters alone, but not all together.
client.search({
index: 'users',
type: 'user',
body: {
"query": {
//NEED TO FILL THIS IN
}
}
}).then(function(resp){
//Do something with search results
});
First you need to create the mapping for this particular use case.
curl -X PUT "http://$hostname:9200/myindex/mytype/_mapping" -d '{
"mytype": {
"properties": {
"email": {
"type": "string",
"index": "not_analyzed"
},
"nickname": {
"type": "string"
},
"name": {
"type": "string"
}
}
}
}'
Here by making email as not_analyzed , you are making sure only the exact match works.
Once that is done , you need to make the query.
As we have multiple conditions , it would be a good idea to use bool query.
You can combine multiple queries and how to handle them using bool query
Query -
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "qbox"
}
},
{
"prefix": {
"nickname": "qbo"
}
},
{
"match": {
"email": "me#qbox.io"
}
}
]
}
}
}
Using the prefix query , you are telling Elasticsearch that even if the token starts with qbo , qualify it as a match.
Also prefix query might not be very fast , in that case you can go for ngram analyzer - http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/analysis-ngram-tokenizer.html

Resources