Mongodb Atlas create Search Index for substrings using autocomplete - mongodb

I am trying to create a search index for my collection and applying autocomplete to the mapped field call "url". I am planning to tokenize the letter/symbol/digit starting as small as 1 character using nGram.
{
"mappings": {
"dynamic": false,
"fields": {
"url": {
"type": "autocomplete",
"analyzer": "lucene.standard",
"tokenization": "nGram",
"minGrams": 1,
"maxGrams": 100
}
}
}
}
However with this indexing, when I try to query for substrings using their search tester, it didn't return as expected.
For example when I try query "red", no result came back. But the expected output should be at least:
https://reddit.com/r/programmerhumor
Where did the mapping went wrong?

Related

Which analyzer to use on specific strings?

I have a document in my collection with a property name like this:
name: [{Value: "steel 0.8x1000x2000mm"}]
Now I'm trying to create a search index for it, so far looks like this:
...
"name": {
"fields": {
"Value": [
{
"analyzer": "lucene.finnish",
"searchAnalyzer": "lucene.finnish",
"type": "string"
},
{
"dynamic": true,
"type": "document"
}
]
},
"type": "document"
},
...
And it works pretty fine except for such documents. The issue is that the query 0.8x1000x2000 doesn't match anything, though 0.8x1000x2000mm works fine.
I guess I'm using the wrong analyzer, but can't really figure out which one should I. Or I should make a custom one?

Grafana Postgres Error When Using Where Query That Can Have Multiple Values

I have a Grafana website pulling from a PostgreSQL database. In the dashboard, I am trying to create a line graph, with a filter set on two of the columns (project and epic). The filter works fine for the project (probably because there is just one project value, and all rows in the database are set with that value).
But when I try to filter on the "epic", it will only work for a single choice. The 'All' choice gives me the below error:
pq: syntax error at or near ","
Below is a screenshot of how I'm trying to configure this filter.
Also note the epic is tied to a variable, and below is a screenshot of how I've setup that variable
Edit
Requested Generated SQL
{
"request": {
"url": "api/tsdb/query",
"method": "POST",
"data": {
"from": "1577958613797",
"to": "1609224964157",
"queries": [
{
"refId": "A",
"intervalMs": 21600000,
"maxDataPoints": 1470,
"datasourceId": 4,
"rawSql": "SELECT\n \"timestamp\" AS \"time\",\n cycle_time AS \"cycle_time\"\nFROM issue_metrics\nWHERE\n $__timeFilter(\"timestamp\") AND\n project = 'LUSFPRO3' AND\n epic = 'LUSFPRO3-68','LUSFPRO3-2','LUSFPRO3-69'\nORDER BY 1",
"format": "time_series"
}
]
},
"hideFromInspector": false
},
"response": {
"results": {
"A": {
"error": "pq: syntax error at or near \",\"",
"refId": "A",
"meta": {
"executedQueryString": "SELECT\n \"timestamp\" AS \"time\",\n cycle_time AS \"cycle_time\"\nFROM issue_metrics\nWHERE\n \"timestamp\" BETWEEN '2020-01-02T09:50:13.797Z' AND '2020-12-29T06:56:04.157Z' AND\n project = 'LUSFPRO3' AND\n epic = 'LUSFPRO3-68','LUSFPRO3-2','LUSFPRO3-69'\nORDER BY 1"
},
"series": null,
"tables": null,
"dataframes": null
}
},
"message": "pq: syntax error at or near \",\""
}
}
That multivalue variable generates wrong SQL syntax:
epic = 'LUSFPRO3-68','LUSFPRO3-2','LUSFPRO3-69'
GUI editor is good only for simple queries. Toogle to text edit mode and update epic condition in the query to:
epic IN ($Epic)
so that generates correct SQL syntax:
epic IN ('LUSFPRO3-68','LUSFPRO3-2','LUSFPRO3-69')

Elastic Search Fuzzy Search root and nested fields

I am new to Elastic Search and facing a couple of issues when querying. I have a simple Mongodb database with collections of cities and places of interest. Each collection has a cityName and other details like website etc, and also a places object array. This is my mapping;
{
"mappings": {
"properties": {
"cityName": {
"type": "text"
},
"phone": {
"type": "keyword"
},
"email": {
"type": "keyword"
},
"website": {
"type": "keyword"
},
"notes": {
"type": "keyword"
},
"status": {
"type": "keyword"
},
"places": {
"type": "nested",
"properties": {
"name": {
"type": "text"
},
"status": {
"type": "keyword"
},
"category": {
"type": "keyword"
},
"reviews": {
"properties": {
"rating": {
"type": "long"
},
"comment": {
"type": "keyword"
},
"user": {
"type": "nested"
}
}
}
}
}
}
}
}
I need a fuzzy query where user can search both cityName and places.name, however I get results when I search a single word, adding multiple words return 0 hits. I am sure I am missing something here because I started learning elastic search 2 days ago. The following query returns results because I have a document with cityName: Islamabad and places array having objects that have the keyword Islamabad in their name, in some places the keyword Islamabad is at the beginning of the place.name and in some places objects it might be in the middle or end
This is what I am using : Returns results when only one word
{
"query": {
"bool": {
"should": [
{
"fuzzy": {
"cityName": "Islamabad"
}
},
{
"nested": {
"path": "places",
"query": {
"fuzzy": {
"places.name": "Islamabad"
}
}
}
}
]
}
}
}
Adding another word, say, club, to the above query returns 0 hits when I actually do have places having names Islamabad club and Islamabad Golf club
Problem
The search query is sent from an app and so it is dynamic, so the term to search is same for both cityName and places.name AND places.name doesn't always have the cityName in it.
What do I need exactly??
I need a query where I can search cityName and the array of places (only searching places.name). The query should be of Fuzzy type so that it still returns results if the word Islamabad is spelled like Islambad or even return results for Islam or Abad. And the query should also return results for multiple words, I am sure am I doing something wrong there. Any help would be appreciated.
**P.S : ** I am actually using MongoDB as my database but migrating to Elastic Search ONLY for improving our search feature. I tried different ways with MongoDB, used the mongoose-fuzzy-searching npm module but that didn't work, so if there's a simpler solution for MongoDB please share that too.
Thanks.
EDIT 1:
I had to change the structure (mapping) of my data. Now I have 2 separate indices, one for cities with city details and a cityId and another index for all places, each place has a cityId which will be used for joining later if needed. Each place also has a cityName key so I will only be searching the places index because it has all the details (place name and city name).
I have a city including the word Welder's in it's name and also the some places inside the same location have the word Welder's in their name, which have a type:text. However when searched for welder both of the following queries don't return these documents, a search for welders OR welder's does return these documents. I am not sure why welder won't match with Welder's*. I didn't specify any analyzer during the creation of both the indices and neither am I explicitly defining it in the query can anyone help me out with this query so it behaves as expected:
Query 1 :
{
"query": {
"bool": {
"should": [
{
"match": {
"name": {
"query": "welder",
"fuzziness": 20
}
}
},
{
"match": {
"cityName": {
"query": "welder",
"fuzziness": 20
}
}
}
]
}
}
}
Query 2 :
{
"query": {
"match": {
"name": {
"query": "welder",
"fuzziness": 20
}
}
}
}
the fuzzy query is meant to be used to find approximations of your complete query within a certain distance :
To find similar terms, the fuzzy query creates a set of all possible
variations, or expansions, of the search term within a specified edit
distance. The query then returns exact matches for each expansion.
If you you cant to allow fuzzy matching of individual terms in your query your need to use a match query with the fuzziness activated.
POST <your_index>/_search
{
"query": {
"bool": {
"should": [
{
"match": {
"cityName": {
"query": "Islamabad golf",
"fuzziness": "AUTO"
}
}
},
{
"nested": {
"path": "places",
"query": {
"match": {
"places.name": {
"query": "Islamabad golf",
"fuzziness": "AUTO"
}
}
}
}
}
]
}
}
}
Reminder: Fuzziness in elasticsearch allow at max 2 corrections per term. SO you will never be able to match Islam with Islamabad since there are 4 changes between those terms.
For more information on distance and fuzziness parameters please refer to this documentation page fuzziness parameters

MongoDb query - aggregation, group, filter, max

I am trying to figure out specific mongoDb query, so far unsuccessfully.
Documents in my collections looks someting like this (contain more attributes, which are irrelevant for this query):
[{
"_id": ObjectId("596e01b6f4f7cf137cb3d096"),
"code": "A",
"name": "name1",
"sys": {
"cts": ISODate("2017-07-18T12:40:22.772Z"),
}
},
{
"_id": ObjectId("596e01b6f4f7cf137cb3d097"),
"code": "A",
"name": "name2",
"sys": {
"cts": ISODate("2017-07-19T12:40:22.772Z"),
}
},
{
"_id": ObjectId("596e01b6f4f7cf137cb3d098"),
"code": "B",
"name": "name3",
"sys": {
"cts": ISODate("2017-07-16T12:40:22.772Z"),
}
},
{
"_id": ObjectId("596e01b6f4f7cf137cb3d099"),
"code": "B",
"name": "name3",
"sys": {
"cts": ISODate("2017-07-10T12:40:22.772Z"),
}
}]
What I need is to get current versions of documents, filtered by code or name, or both. Current version means that from two(or more) documents with same code, I want pick the one which has latest sys.cts date value.
So, result of this query executed with filter name="name3" would be the 3rd document from previous list. Result of query without any filter would be 2nd and 3rd document.
I have an idea how to construct this query with changed data model but I was hoping someone could lead me right way without doing so.
Thank you

Is there any ways in mongodb acts like SQL "drop column"?

I have some mongodb documents which structure like:
{
"_id": ObjectId("58c212b06ca3472b902f9fdb"),
"Auction name": "Building",
"Estimated price": "23,660,000",
"Auction result": "success",
"Url": "https://someurl.htm",
"match_id": "someid",
"Final price": "17,750,000",
"Area": [
{
"Area": "696.77"
}
]
}
The "match_id" is used for update query and after that I don't need this entry anymore.
Is there any idea to drop this entry and keep the rest of the document?
Have you tried simpily using an update query to unset the field like the following
db.products.update(
{},
{ $unset: { match_id: "" } }
)
Keep in mind that the first set of curly braces has been intentionally left blank so that your update query matches every entry in your collection