Can I use optional filters in Azure Cognitive Search - azure-cognitive-search

I would like to implement a search logic like this "Give me all articles from the index that match my term and prefer articles from a certain category".
In elastic search it is possible to implement this with "should" Boolean queries: https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html
should The clause (query) should appear in the matching document.
But I am not sure how to implement this in Azure Cognitive Search. One option would be to make a search for all articles that are not in the category and then all all that are in the category and make some kind of global order based on the scoring.
Is there a built-in functionality?

You should be able to achieve the desired behavior by using the search.ismatchscoring which allows writing full-text search in filter expressions.
This filter expression will ensure that skateboards is in the Title and search for sports in the Category to contribute to scoring but it will still return documents in other categories due to the or statement:
search.ismatchscoring('skateboards', 'Title') and (search.ismatchscoring('sports', 'Category') or search.ismatchscoring('*'))

What you are asking for is supported via a functionality called Term Boosting in Azure Search. In your example you have some search terms that must exist. But, you don't actually know if those terms are found at all in a category you have in mind. If they do, you would like to boost these to the top.
Your search terms is a filter that determines if an article should be included.
Your requested category is a preference.
USE CASE
Let's assume that you have an index with music. You use the following index specification (simplified for example).
{
"fields": [
{"name": "Id", "type": "Edm.String", "searchable": false, "filterable": true, "retrievable": true, "sortable": true, "facetable": false, "key": true, "indexAnalyzer": null, "searchAnalyzer": null, "analyzer": null, "synonymMaps": [] },
{"name": "Title", "type": "Edm.String", "searchable": true, "filterable": true},
{"name": "Genre", "type": "Edm.String", "searchable": true, "filterable": true},
{"name": "Artist", "type": "Edm.String", "searchable": true, "filterable": true}
],
}
The index contains the following items.
{
"value": [
{
"#search.action": "mergeOrUpload",
"Id": "1",
"Title": "We will rock you",
"Genre": "Classical",
"Artist": "London Symphony"
},
{
"#search.action": "mergeOrUpload",
"Id": "2",
"Title": "We will rock you",
"Genre": "Rock",
"Artist": "Queen"
},
{
"#search.action": "mergeOrUpload",
"Id": "3",
"Title": "Bohemian Rhapsody",
"Genre": "Rock",
"Artist": "Queen"
}
]
}
Now, assume that you are looking for the song we will rock you. If you simply searched for those terms, you would get two hits. Notice that the item with the genre Rock is scored higher. This is because of the term frequency for your search term rock. Rock occurs both in the genre and the title.
{
"#odata.count": 2,
"value": [
{
"#search.score": 1.4384104,
"Id": "2",
"Title": "We will rock you",
"Genre": "Rock",
"Artist": "Queen"
},
{
"#search.score": 1.1507283,
"Id": "1",
"Title": "We will rock you",
"Genre": "Classical",
"Artist": "London Symphony"
}
]
}
In your case, you would prefer content from a specific category. Translated to this example, assume that you would really prefer hits from the Classical genre. You could construct your query with a filter, like this.
we will rock you Genre:"Classical"
Since you are filtering, you will only get 1 hit. Notice that the score is now higher too.
{
"#odata.count": 1,
"value": [
{
"#search.score": 1.4384104,
"Id": "1",
"Title": "We will rock you",
"Genre": "Classical",
"Artist": "London Symphony"
}
]}
If you apply boosting, say by a factor of 10, you will see that the score increases. E.g.
we will rock you Genre:"Classical"^10
{
"#odata.count": 1,
"value": [
{
"#search.score": 4.0275493,
"Id": "1",
"Title": "We will rock you",
"Genre": "Classical",
"Artist": "London Symphony"
}
]}
But, lets assume that you don't know if there are multiple versions in different genres. What you want is all versions of 'we will rock you', but if there is a hit from the classical genre, that's what you prefer. This is a different question (and what you are asking if my interpretation is correct).
(we will rock you) OR (we will rock you Genre:"Classical"^10)
This produces 2 results, with the Classical version on top.
"#odata.count": 2,
"value": [
{
"#search.score": 5.1782775,
"Id": "1",
"Title": "We will rock you",
"Genre": "Classical",
"Artist": "London Symphony"
},
{
"#search.score": 1.4384104,
"Id": "2",
"Title": "We will rock you",
"Genre": "Rock",
"Artist": "Queen"
}
]

Related

Array inside Object inside Array - method map don't want work - Cannot read properties of undefined

i'm a new in React. I downloaded the api request and need length array comments and other properties, but React all time msg to me: Cannot read properties of undefined (reading 'length') or Cannot read properties of undefined (reading 'map').
Where is a problem ?
My array from api is:
const myArrayApi = [
{
"id": 1,
"title": "Add tags for solutions",
"category": "enhancement",
"upvotes": 112,
"status": "suggestion",
"description": "Easier to search for solutions based on a specific stack.",
"comments": [
{
"id": 1,
"content": "Awesome idea! Trying to find framework-specific projects within the hubs can be tedious",
"user": {
"image": "./assets/user-images/image-suzanne.jpg",
"name": "Suzanne Chang",
"username": "upbeat1811"
}
},
{
"id": 2,
"content": "Please use fun, color-coded labels to easily identify them at a glance",
"user": {
"image": "./assets/user-images/image-thomas.jpg",
"name": "Thomas Hood",
"username": "brawnybrave"
}
}
]
},
{
"id": 2,
"title": "Add a dark theme option",
"category": "feature",
"upvotes": 99,
"status": "suggestion",
"description": "It would help people with light sensitivities and who prefer dark mode.",
"comments": [
{
"id": 3,
"content": "Also, please allow styles to be applied based on system preferences. I would love to be able to browse Frontend Mentor in the evening after my device’s dark mode turns on without the bright background it currently has.",
"user": {
"image": "./assets/user-images/image-elijah.jpg",
"name": "Elijah Moss",
"username": "hexagon.bestagon"
}
},
{
"id": 4,
"content": "Second this! I do a lot of late night coding and reading. Adding a dark theme can be great for preventing eye strain and the headaches that result. It’s also quite a trend with modern apps and apparently saves battery life.",
"user": {
"image": "./assets/user-images/image-james.jpg",
"name": "James Skinner",
"username": "hummingbird1"
},
"replies": [
{
"content": "While waiting for dark mode, there are browser extensions that will also do the job. Search for 'dark theme' followed by your browser. There might be a need to turn off the extension for sites with naturally black backgrounds though.",
"replyingTo": "hummingbird1",
"user": {
"image": "./assets/user-images/image-anne.jpg",
"name": "Anne Valentine",
"username": "annev1990"
}
},
{
"content": "Good point! Using any kind of style extension is great and can be highly customizable, like the ability to change contrast and brightness. I'd prefer not to use one of such extensions, however, for security and privacy reasons.",
"replyingTo": "annev1990",
"user": {
"image": "./assets/user-images/image-ryan.jpg",
"name": "Ryan Welles",
"username": "voyager.344"
}
}
]
}
]
},
{
"id": 3,
"title": "Q&A within the challenge hubs",
"category": "feature",
"upvotes": 65,
"status": "suggestion",
"description": "Challenge-specific Q&A would make for easy reference.",
"comments": [
{
"id": 5,
"content": "Much easier to get answers from devs who can relate, since they've either finished the challenge themselves or are in the middle of it.",
"user": {
"image": "./assets/user-images/image-george.jpg",
"name": "George Partridge",
"username": "soccerviewer8"
}
}
]
},
{
"id": 4,
"title": "Add image/video upload to feedback",
"category": "enhancement",
"upvotes": 51,
"status": "suggestion",
"description": "Images and screencasts can enhance comments on solutions.",
"comments": [
{
"id": 6,
"content": "Right now, there is no ability to add images while giving feedback which isn't ideal because I have to use another app to show what I mean",
"user": {
"image": "./assets/user-images/image-javier.jpg",
"name": "Javier Pollard",
"username": "warlikeduke"
}
},
{
"id": 7,
"content": "Yes I'd like to see this as well. Sometimes I want to add a short video or gif to explain the site's behavior..",
"user": {
"image": "./assets/user-images/image-roxanne.jpg",
"name": "Roxanne Travis",
"username": "peppersprime32"
}
}
]
},
{
"id": 5,
"title": "Ability to follow others",
"category": "feature",
"upvotes": 42,
"status": "suggestion",
"description": "Stay updated on comments and solutions other people post.",
"comments": [
{
"id": 8,
"content": "I also want to be notified when devs I follow submit projects on FEM. Is in-app notification also in the pipeline?",
"user": {
"image": "./assets/user-images/image-victoria.jpg",
"name": "Victoria Mejia",
"username": "arlen_the_marlin"
},
"replies": [
{
"content": "Bumping this. It would be good to have a tab with a feed of people I follow so it's easy to see what challenges they’ve done lately. I learn a lot by reading good developers' code.",
"replyingTo": "arlen_the_marlin",
"user": {
"image": "./assets/user-images/image-zena.jpg",
"name": "Zena Kelley",
"username": "velvetround"
}
}
]
},
{
"id": 9,
"content": "I've been saving the profile URLs of a few people and I check what they’ve been doing from time to time. Being able to follow them solves that",
"user": {
"image": "./assets/user-images/image-jackson.jpg",
"name": "Jackson Barker",
"username": "countryspirit"
}
}
]
},
{
"id": 6,
"title": "Preview images not loading",
"category": "bug",
"upvotes": 3,
"status": "suggestion",
"description": "Challenge preview images are missing when you apply a filter."
},
{
"id": 7,
"title": "More comprehensive reports",
"category": "feature",
"upvotes": 123,
"status": "planned",
"description": "It would be great to see a more detailed breakdown of solutions.",
"comments": [
{
"id": 10,
"content": "This would be awesome! It would be so helpful to see an overview of my code in a way that makes it easy to spot where things could be improved.",
"user": {
"image": "./assets/user-images/image-victoria.jpg",
"name": "Victoria Mejia",
"username": "arlen_the_marlin"
}
},
{
"id": 11,
"content": "Yeah, this would be really good. I'd love to see deeper insights into my code!",
"user": {
"image": "./assets/user-images/image-jackson.jpg",
"name": "Jackson Barker",
"username": "countryspirit"
}
}
]
},
{
"id": 8,
"title": "Learning paths",
"category": "feature",
"upvotes": 28,
"status": "planned",
"description": "Sequenced projects for different goals to help people improve.",
"comments": [
{
"id": 12,
"content": "Having a path through the challenges that I could follow would be brilliant! Sometimes I'm not sure which challenge would be the best next step to take. So this would help me navigate through them!",
"user": {
"image": "./assets/user-images/image-george.jpg",
"name": "George Partridge",
"username": "soccerviewer8"
}
}
]
},
{
"id": 9,
"title": "One-click portfolio generation",
"category": "feature",
"upvotes": 62,
"status": "in-progress",
"description": "Add ability to create professional looking portfolio from profile.",
"comments": [
{
"id": 13,
"content": "I haven't built a portfolio site yet, so this would be really helpful. Might it also be possible to choose layout and colour themes?!",
"user": {
"image": "./assets/user-images/image-ryan.jpg",
"name": "Ryan Welles",
"username": "voyager.344"
}
}
]
},
{
"id": 10,
"title": "Bookmark challenges",
"category": "feature",
"upvotes": 31,
"status": "in-progress",
"description": "Be able to bookmark challenges to take later on.",
"comments": [
{
"id": 14,
"content": "This would be great! At the moment, I'm just starting challenges in order to save them. But this means the My Challenges section is overflowing with projects and is hard to manage. Being able to bookmark challenges would be really helpful.",
"user": {
"image": "./assets/user-images/image-suzanne.jpg",
"name": "Suzanne Chang",
"username": "upbeat1811"
}
}
]
},
{
"id": 11,
"title": "Animated solution screenshots",
"category": "bug",
"upvotes": 9,
"status": "in-progress",
"description": "Screenshots of solutions with animations don’t display correctly."
},
{
"id": 12,
"title": "Add micro-interactions",
"category": "enhancement",
"upvotes": 71,
"status": "live",
"description": "Small animations at specific points can add delight.",
"comments": [
{
"id": 15,
"content": "I'd love to see this! It always makes me so happy to see little details like these on websites.",
"user": {
"image": "./assets/user-images/image-victoria.jpg",
"name": "Victoria Mejia",
"username": "arlen_the_marlin"
},
"replies": [
{
"content": "Me too! I'd also love to see celebrations at specific points as well. It would help people take a moment to celebrate their achievements!",
"replyingTo": "arlen_the_marlin",
"user": {
"image": "./assets/user-images/image-suzanne.jpg",
"name": "Suzanne Chang",
"username": "upbeat1811"
}
}
]
}
]
}
]
const MyArrayFromApi = () => {
const [arrayApi, setArrayApi] = useState(myArrayApi);
return (
<div>
{arrayApi.map((elementApi => {
return (
<div key={elementApi.id}>
<div>
<h1>{elementApi.title}</h1>
<p>{elementApi.category}</p>
<p>{elementApi.upvotes}</p>
<p>{elementApi.description}</p>
</div>
{elementApi.comments.map((elementComments => {
return (
<div key={elementComments.id}><p>{elementComments.content}</p></div>
)
}))}
</div>
)
}))}
</div>
)
}
export { MyArrayFromApi }
enter image description here
The error happened because of "elementApi.comments.map".
There are some items that don't have "comments" property. e.g. id = 6, 11
So please change "elementApi.comments.map" to "elementApi.comments?.map".
Incorrect use of parentheses with arrow function arguments. Use them like the below sample code. Or you can ignore them if you have only one argument: arrayApi.map(elementApi => {
//....rest of the code
{arrayApi.map((elementApi) => {
return (
//...
)
})}
</div>
//...
Same issue with elementApi.comments.map(...
Also with elementsApi.comments, in some objects the comments are undefined. So in order to deal with this you need to call this attribute with the optional chaining operator (?.)
Ex: elementApi.comments?.map(...
From MDN
The optional chaining operator provides a way to simplify accessing values through connected objects when it's possible that a reference or function may be undefined or null
here is the solution to this https://stackblitz.com/edit/react-cdwvfz?file=src/App.js
I have used The optional chaining operator (?.) (comments?). this operator enables you to read the value of a property located deep within a chain of connected objects without having to check that each reference in the chain is valid.
like in the myArrayApi array, some objects did not have comment key so after using this operator, the undefined error would not appear
const [arrayApi, setArrayApi] = useState(myArrayApi);
return (
<div>
{arrayApi.map((elementApi) => {
return (
<div key={elementApi.id}>
<div>
<h1>{elementApi.title}</h1>
<p>{elementApi.category}</p>
<p>{elementApi.upvotes}</p>
<p>{elementApi.description}</p>
</div>
{elementApi?.comments?.map((elementComments) => {
return (
<div key={elementComments.id}>
<p>{elementComments.content}</p>
</div>
);
})}
</div>
);
})}
</div>
);

reindex elasticsearch if insert new elements into array of document

I am new in elasticsearch. I have following type of structure into my ES.
PUT /my_index/blogpost/1
{
"title": "Nest eggs",
"body": "Making your money work...",
"tags": [ "cash", "shares" ],
"comments": [
{
"name": "John Smith",
"comment": "Great article",
"age": 28,
"stars": 4,
"date": "2014-09-01"
},
{
"name": "Alice White",
"comment": "More like this please",
"age": 31,
"stars": 5,
"date": "2014-10-22"
}
]
}
I found documents are immutable: they cannot be changed, only replaced. So I want to know when I push or pull any object from "comments" array then what will happen? Will my_index will be reindexed or 1 document will be reindexed?

How do I read a nested structure from solr?

I am lost and need your advice. I have a nested Solr Document containing multiple levels of sub-documents. Here is a JSON example so you can see the full structure:
{
"id": "Test Library",
"description": "example of nested document",
"content_type": "library",
"authors": [{
"id": "author1",
"content_type": "author",
"name": "First Author",
"books": [{
"id": "book1",
"content_type": "book",
"title": "title of book 1"
}],
"shortStories": [{
"id": "shortStory1",
"content_type": "shortStory",
"title": "title of short story 1"
}]
},
{
"id": "author2",
"content_type": "author",
"name": "Second Author",
"books": [{
"id": "book1",
"content_type": "book",
"title": "title of book 1"
}],
"shortStories": [{
"id": "shortStory1",
"content_type": "shortStory",
"title": "title of short story 1"
}]
}]
}
I want to query for a document and retrieve the nested structure. I tried using the ChildDocumentTranformerFactory but it flattened the result to be just Library and all other documents as children:
{
"id": "Test Library",
"description": "example of nested document",
"content_type": "library",
"_childDocuments_":[
{"id": "author1",
"content_type": "author",
"name": "First Author"
},
{"id": "book1",
"content_type": "book",
"title": "title of book 1"
},
{
"id": "shortStory1",
"content_type": "shortStory",
"title": "title of short story 1"
},
{
"id": "author2",
"content_type": "author",
"name": "Second Author"
},
{
"id": "book1",
"content_type": "book",
"title": "title of book 1"
},
{
"id": "shortStory1",
"content_type": "shortStory",
"title": "title of short story 1"
}
]
}
Here are the query parameters I used:
q={!parent which='content_type:library'}
df=id
fl=*,[child parentFilter='content_type:library' childFilter='id:*']
wt=json
indent=true
What is the best way to read the nested structure from Solr? Do I need to do some sort of faceting?
I am using Solr version 5.2.1
Unfortunately solr does not support that right now.
ChildDocTransformerFactory returns all descendant documents of each parent document matching your query in a flat list nested inside the matching parent document
Not sure if there is a work around for this.
Please look into Block Join to virtually relate the parent and child.
https://github.com/lucidworks/solrj-nested-docs

Implementing Real Time Search in MEAN

I've developed an e-commerce app and I need to fetch key to key real time search results from MongoDB while using Angular, Node, Express, etc.
Two Questions:
1. Is elasticsearch my answer, if so any examples or sources to learn apart from the mongolastic module on npm directory.
2. I also digged around AnguarJS official website and found they are using lunrSearch. I need search results offered like Google in a tabular format.
So far, I've put up real time search from a Json file comprising of several keywords and them hyperlinking to the real product.
My
keywords.json
[
{
"title": "Apple",
"Department": "Produce",
"Category": "fruits"
},
{
"title": "Orange",
"Department": "Produce",
"Category": "fruits"
},
{
"title": "Banana",
"Department": "Produce",
"Category": "fruits"
},
{
"title": "Cauliflower",
"Department": "Produce",
"Category": "vegetables"
},
{
"title": "Lays",
"Department": "Bakery",
"Category": "chips"
},
{
"title": "Olive Oil",
"Department": "Produce",
"Category": "oil"
},
{
"title": "Shampoo",
"Department": "PersonalCare",
"Category": "haircare"
}
]
Any npm packages, controller example, just about any advice would be helpful.
Thanks for being patient.

Problems while creating bigquery table schema

Using Google BigQuery I need to manually create a table and load the data contained in the json file. I am using BigQuery UI, but unable to define the schema for the data, a sample of the same is given below. The problem comes with the json array as below.
{"Author": "Pranesh Nageshwar", "headline": "Train trashes crashed car", "charactercount": 1027, "dateLive": "2014-01-14", "keywords": ["train crash", "freight train", "online reporting page", "side road", "blue mountains", "new south wales", "australia", "blaxland", "new south wales", "australia", "crime stoppers", "springwood police station", "train tracks"], "id": "1226801299367"}
Arrays of values in BigQuery are represented as a field with a repeated mode. The schema you want is probably the following. If you copy and paste this into the box in the web UI, I think it will work.
[
{
"name": "author",
"type": "string"
},
{
"name": "headline",
"type": "string"
},
{
"name": "charactercount",
"type": "integer"
},
{
"name": "dateLive",
"type": "string",
},
{
"name": "keywords",
"type": "string",
"mode": "repeated"
},
{
"name": "id",
"type": "string"
}
]

Resources