Elasticsearch search with multi fields - javascript

How can i create body for elasticsearch like this
select * from table where full_name like '%q%' or address like '%q%' or description like '%q%' order by full_name , description , address

A wildcard query can be very expensive, especially if you search in several fields. The right way to do this is by using an nGram token filter on the fields you want to search only a part of.
First you create an index like below with a custom analyzer that will slice and dice your fields into searchable tokens:
curl -XPUT localhost:9200/tests -d '{
"settings": {
"analysis": {
"analyzer": {
"substring_analyzer": {
"tokenizer": "standard",
"filter": ["lowercase", "substring"]
}
},
"filter": {
"substring": {
"type": "nGram",
"min_gram": 1,
"max_gram": 15
}
}
}
},
"mappings": {
"test": {
"properties": {
"full_name": {
"type": "string",
"analyzer": "substring_analyzer"
},
"address": {
"type": "string",
"analyzer": "substring_analyzer"
},
"description": {
"type": "string",
"analyzer": "substring_analyzer"
}
}
}
}
}'
Then you can index a few docs:
curl -XPUT localhost:9200/tests/test/_bulk -d '
{"index":{"_id": 1}}
{"full_name": "Doe", "address": "1234 Quinn Street", "description": "Lovely guy"}
{"index":{"_id": 2}}
{"full_name": "Brennan", "address": "4567 Main Street", "description": "Not qualified"}
{"index":{"_id": 3}}
{"full_name": "Quantic", "address": "1234 Quinn Street", "description": "New friend"}
'
Finally, you can search with a query equivalent to your SQL query above and all three test documents will match:
curl -XPUT localhost:9200/tests/test/_search -d '{
"query": {
"bool": {
"should": [
{
"match": {
"full_name": "q"
}
},
{
"match": {
"address": "q"
}
},
{
"match": {
"description": "q"
}
}
]
}
}
}'

You can try the following. . .
https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-wildcard-query.html
`
{
"wildcard" : { "user" : "ki*y" }
}
`

Related

AWS DataExchange API fetch returning response '404: Asset not found'

I'm trying to fetch data from an AWS DataExchange provider based on their company's API specification.
I'm using the AWS Node.JS NPM modules 'aws-sdk' and '#aws-sdk/client-dataexchange'.
However, every query I've written is returning the error '404: Asset not found'.
I'm subscribed to use the API and I've verified that all my AWS credentials, policies and IAM keys give me permission to access the API.
Could someone please help me identify what's wrong with my query in relation to the API specification.
Thanks!
The response I get looks like below:
404: Asset not found
'$fault': 'client',
'$metadata': {
httpStatusCode: 404,
requestId: 'b7e6e691-xxxxxxx7657201138a4',
extendedRequestId: undefined,
cfId: 'dBQBwlCE8cXp4--xxxxxxxxxxx3j2lTfxywUezCPEA6nusJCJg==',
attempts: 1,
totalRetryDelay: 0
},
ResourceType: 'ASSET',
ResourceId: 'e055c882bde1fa3xxxxxxxxx'
}
My current request 'body' looks like below:
Body: JSON.stringify({
"description": "GraphQL query for the Ursa Space Imagery Catalog.",
"content": {
"application/graphql": {
"schema": {
"$ref": "#/components/schemas/CatalogSearchRequest"
},
"query": {
"description": "Limit the number of records in a response.",
"value":"{\n availablemetadatarecord(\n limit: 20\n content: { catalogProperties: { vendor: { eq: \"ICEYE\" } } }\n ) {\n assignedId\n }\n}\n"
}
}
},
"required": true
}),
The DataExchange provider's actual API specification looks like below:
{
"openapi": "3.0.1",
"info": {
"title": "image-services",
"description": "API Gateway for integration of Platform Services into AWS Data Exchange",
"version": "2022-03-03T20:04:18Z"
},
"servers": [
{
"url": ""
}
],
"paths": {
"/psdm/graphql": {
"post": {
"requestBody": {
"description": "GraphQL query for the Catalog in the form of:\n\n `{\n availablemetadatarecord(\n QUERYPARAMS\n ) { \n FIELDLIST\n } \n }`\n",
"content": {
"application/graphql": {
"schema": {
"$ref": "#/components/schemas/CatalogSearchRequest"
},
"examples": {
"Limit returned data": {
"description": "Limit the number of records in a response.\n\nIn your query, simply specify `limit: <int>` \n",
"value": "{\n availablemetadatarecord(\n limit: 10\n content: { catalogProperties: { vendor: { eq: \"EYE\" } } }\n ) {\n assignedId\n }\n}\n"
}
}
}
},
"required": true
},
"responses": {
"200": {
"description": "200 response",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CatalogSearchResponse"
}
}
}
}
},
"security": [
{
"sigv4": []
}
]
}
}
},
"components": {
"schemas": {
"CatalogSearchRequest": {
"title": "CatalogSearchRequest",
"type": "object"
},
"CatalogSearchResponse": {
"title": "Catalog Search Response",
"required": [
"data",
"paginationInfo"
],
"type": "object",
"properties": {
"paginationInfo": {
"type": "object",
"properties": {
"recordsInPage": {
"type": "integer"
},
"nextOffset": {
"type": "integer"
}
}
},
"data": {
"type": "object",
"properties": {
"availablemetadatarecord": {
"type": "array",
"description": "Records returned by query",
"items": {
"type": "object"
}
}
}
}
}
}
},
"securitySchemes": {
"sigv4": {
"type": "apiKey",
"name": "Authorization",
"in": "header",
"x-amazon-apigateway-authtype": "awsSigv4"
}
}
}
}

how to fetch items if any search keyword matched?

I have this document in my elastic DB.I am using this package
https://www.npmjs.com/package/#elastic/elasticsearch
I am searching on title.
I am doing like this.
const result= await client.search({
index: 'products',
"query": {
"bool": {
"should": [
{
"wildcard": { "title": "*" + search + "*" }
}
],
"minimum_should_match": 1
}
}
when I search "title" this issue . it give me one result but When I am seacrhing i have issue . it is giving zero or 0 result.why ? is it possible to fetch that data.issue keyword is present in first collection why it is not picking ?
[
{
"_index": "products",
"_id": "wZRh3n8Bs9qQzO6fvTTS",
"_score": 1.0,
"_source": {
"title": "laptop issues",
"description": "laptop have issue present in according"
}
},
{
"_index": "products",
"_id": "wpRh3n8Bs9qQzO6fvzQM",
"_score": 1.0,
"_source": {
"title": "buy mobile",
"description": "mobile is in Rs 250"
}
},
{
"_index": "products",
"_id": "w5Rh3n8Bs9qQzO6fvzTz",
"_score": 1.0,
"_source": {
"title": "laptop payment",
"description": "laptop payment is given in any way"
}
}
]
how to search on keywords? any keyword match . I need to pick that whole colloection
If you want to match only some of the word from query then you can use match query with operator set to or.
{
"query": {
"match": {
"title": {
"query": "i have issues",
"operator": "or"
}
}
}
}
Update
To run the query which you mentioned in comment, You can use match_bool_prefix query.
{
"query": {
"match_bool_prefix": {
"title": {
"query": "i have issu"
}
}
}
}

Using the "watch" field in "description" in JSON editor

I'm using a JSON configuration schema which gets pushed to a website which should by using this JSON editor. And I would like to have the user input shown in the description field. Here is a snippet of the JSON file:
{
"type": "object",
"required": [
"file_name"
],
"properties": {
"file_name": {
"type": "string",
"title": "<h3>Table name</h3>",
"description": "Only alphanumeric characters dash and underscores are allowed.</br>Your data will be loaded to some_path.{your table name}",
"options": {
"inputAttributes": {
"placeholder": "your table name"
}
},
"propertyOrder": 100
}
}
}
I would like to have the "Table name" inputted by the user in the "description" field instead of {your table name}. According to the documentation you can use the "watch" variable:
{
"type": "object",
"properties": {
"first_name": {
"type": "string"
},
"last_name": {
"type": "string"
},
"full_name": {
"type": "string",
"template": "{{fname}} {{lname}}",
"watch": {
"fname": "first_name",
"lname": "last_name"
}
}
}
}
But this doesn't work in the "description" field. Any ideas how I can deal with this?

How to add preference to mutliple fields in elastic search query?

I have the following data:
makeStr: xerox
modelStr: Designjet 1050C
I want it to match
xerox
Designjet 1050C Plus Printer
but it is matching
canon
DesignJet 1050C
and currently I have this query
"query": {
"bool": {
"should":
{
"multi_match": {
"query": modelStr,
"type": "most_fields",
"fields": ['model.alphanum']
}
}
,
"filter": [
{
"match": {
"make.blur": makeStr
}
},
{
"match": {
"model.blur": modelStr
}
}
]
}
},
"functions": [{
"field_value_factor": {
"field": "isMpsSupported",
"factor": 1,
"missing": 0
}
}],
"boost_mode": "sum"
}
How do I give preference for makeStr such that it considers both makeStr and modelStr during search.
More preference can be given by using boost. Refer here
Something like makeStr^2 should work.

Nested Query/Select for MongoDB

I'm trying to query my MongoDB structure, specifically the users table to get a specific field, address, but am having difficulty because I'm not sure how to access something a couple levels in users > emails > address:
{
"_id": "BkWk7hq4MRyMAyK4mm",
"createdAt": ISODate("2015-11-15T19:46:41.633Z"),
"services": {
"password": {
"bcrypt": "$2a$10$voVzU3pIVZBd1bfJf1oX4.OMPnzi8zXawYY5REtovPayBJL7dZLWSC"
},
"resume": {
"loginTokens": []
}
},
"emails": [{
"address": "brutus#example.com",
"verified": false,
"provides": "default"
}],
"roles": {
"J8Bhq3uTtdgwZdx3rz": ["guest", "account/profile"]
}
} {
"_id": "3qfCgFz9r5wKjnmymQ",
"createdAt": ISODate("2015-12-15T19:49:05.236Z"),
"emails": [],
"roles": {
"J8aBhq3uTtdgwZx3rz": ["anonymous", "guest"]
},
"services": {
"resume": {
"loginTokens": [{
"when": ISODate("2015-12-15T19:49:05.280Z"),
"hashedToken": "c1ybS3U3+GeC8ZNzGQ3WOctWpudQvv4vND6EzlRygtCQ="
}]
}
}
}
I was trying to use the following:
db.users.find( { emails: { address : "brutus#example.com" } } )
You can query nested objects with dot notation.
db.users.find( { 'emails.address' : "brutus#example.com" } )
Your query is correct but it is querying documents for a complete match. So if your emails field had only address field it would work.
With dot notation you can check just one embedded field for matching.
Take a look at the documentation.

Categories