Check if any value in jsonPath is repeated - javascript

I have a jsonPath as below
{ "book":
[
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Nigel Rees",
"title": "Sword of Honour",
"price": 12.99
}
]}
And Want to check if any author name have got repeated?
I tried
$.book[?(#.author=='Nigel Rees')].find(1)
But, it always throws an exception that found nothing, how could I check that the author='Nigel Rees' occurrences i.e author='Nigel Rees' have a two books?

Depends what you are planning on doing if the authors names exists.
If you only want the objects with author of Nigel Reese you could use a filter.
var booksByNigelReese = book.filter( function(book, index) {
return book.author === 'Nigel Reese'
})
.filter() takes a function that takes the book and index, chooes to accept or rejcet the book into a new array depending if the result of the function is true or false

Related

Search inside array using Elastic Search

I am using Elastic version 6.8, created one index into whose schema is as follow:
{
"properties": {
"title": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
},
"tags": {
"type": "keyword",
"fields": {
"raw": {
"type": "text"
}
}
}
}}
and I have added following documents into it
[{
"title": "one",
"tags": ["html", "css", "javascript"]
}, {
"title": "two",
"tags": ["java", "jsp", "servlet"]
}, {
"title": "three",
"tags": ["spring", "java"]
}, {
"title": "four",
"tags": ["react", "angular", "javascript"]
}, {
"title": "five",
"tags": ["java"]
}, {
"title": "six",
"tags": []
}]
now I have more than 10 millions document in elastic search. Now I want to search following cases:
List all tags. with unique result (using skip, limit) skip value change but limit is fixed.so here I want result like
html,
css,
javascript,
java,
jsp,
servlet,
spring,
react,
angular
Partil search inside tags, it means if I search using act then it should give result as : react this also using skip limit.
How I can get this using Elastic search query. please help me here?
You can find unique possible value by using term aggregation.
GET yourindex/_search
{
"size": 0,
"aggs": {
"all_tags": {
"terms": {
"field": "tags",
"size": 100
}
}
}
}
"size":100 Get at most 100 unique values. Default is 10. You can increase more but it will include cost. You can check more on doc.
For partial search you can use wildcard query OR you can try N-Gram Tokeninzer. Both will allow to do partial search but wildcard query will be costly. You can evaluate according to your use case.

How to find the value of a key in JSON

I have the below JSON and in each object there is an artist and image values. I want a mechanism that when I give a name of the artist it returns the value of the image in the same object. All objects are warped in an array as a JSON.
var iTunes_data = $([{
"title": "title1",
"image": "images/image1.jpg"
},
{
"title": "Hotel California [Rainwave Chiptunes]",
"image": "images/image2.jpg"
},
{
"title": "The Multi-Story Car Park [Rainwave Chiptunes]",
"image": "images/image3.jpg"
},
{
"title": "title4",
"image": "images/image4.jpg"
},
{
"title": "title5",
"image": "images/image2.jpg"
}
]);
function getImage(currentTitle) {
let url = iTunes_data.filter(element => element.title === currentTitle);
return url[0].image;
}
console.log(getImage("title5"));
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
So when I ask for title5 I want to get images/image2.jpg.
I do not want to use the any loop. It has to be more by finding the key and getting the value rather than going through the JSON by a loop, as I find this way faster.
Any idea how to make it working?
Thanks in advance
There's no way to not use a loop. If you want to be more efficient you should take an imperative approach with a for loop and break with a match.
for(let obj in data) {
if(obj.title === title)
// match
break
}
Hope this helps.
To get a specific element from an array without looping, you'll have to know its index. The best you could do is to only loop the array once to map each title to the element's index in the array, here is an example:
const arr = [{
"title": "title1",
"image": "images/image1.jpg"
},
{
"title": "Hotel California [Rainwave Chiptunes]",
"image": "images/image2.jpg"
},
{
"title": "The Multi-Story Car Park [Rainwave Chiptunes]",
"image": "images/image3.jpg"
},
{
"title": "title4",
"image": "images/image4.jpg"
},
{
"title": "title5",
"image": "images/image2.jpg"
}]
const map = arr.reduce((a, c, index) => {
a[c.title] = index;
return a;
},{});
function getImage(title) {
if (!isNaN(map[title])) {
return arr[map[title]].image;
}
}
console.log(getImage('title5'));
I've used a normal array instead of a jQuery object in this example.
I'm assuming the array will not change, you'll have to keep the map in sync if you're going to change the array's content.

Javascript gets undefined on array

I have the following data structure for javascript:
var data = {
"announcements": {
"IFT4S": [{
"id": "D7214",
"read_state": "unread",
"posted_at": "2018-10-25T14:35:54Z",
"title": "Reminder! Systems disruption: 27-28 Oct",
"message": "All University online systems will be unavailable."
}, {
"id": "B399C",
"read_state": "read",
"posted_at": "2018-10-22T09:04:48Z",
"title": "Stem Fair",
"message": "The STEM Careers Fair is taking place on 31 October 2018"
}, {
"id": "6F5EE",
"read_state": "unread",
"posted_at": "2018-10-22T09:04:48Z",
"title": "Smile more, worry less with our FREE course",
"message": "Take part in our Online Mindfulness Programme."
}]
}
}
I want to access the values of the keys "read_state", "posted_at", "title" and "message".
However, when I try data.announcements.IFT4S["title"] or any other key instead of "title" I get the undefined in the console.
What am I doing wrong?
when I try data.announcements.IFT4S["title"] or any other key instead
of "title" I get the undefined in the console. What am I doing wrong?
What you are doing here is trying to access the title key of the IFT4S array.
The issue is that IFT4S doesn't have a title key. Instead, like an array object, it has indexes as keys.
IFT4S = [ {...}, {...}, {...} ]
To access the first element of the IFT4S array you would do it like this
IFT4S[0]
In your case that would return the object at the first position of IFT4S array (index 0)
{
id: "D7214",
read_state: "unread",
posted_at: "2018-10-25T14:35:54Z",
title: "Reminder! Systems disruption: 27-28 Oct",
message: "All University online systems will be unavailable."
}
If you want to get all the titles from all the elements inside IFT4S array you could do this
IFT4S.map(element => element.title)
Array.prototype.map returns a new array where each element is the result of applying the function specified inside map to each element of the original array.
In this case, it would return
[
"Reminder! Systems disruption: 27-28 Oct",
"Stem Fair",
"Smile more, worry less with our FREE course"
]
You have to itrate over the array to get value from an array of object
var data = {
"announcements": {
"IFT4S": [
{
"id": "D7214",
"read_state": "unread",
"posted_at": "2018-10-25T14:35:54Z",
"title": "Reminder! Systems disruption: 27-28 Oct",
"message": "All University online systems will be unavailable."
},
{
"id": "B399C",
"read_state": "read",
"posted_at": "2018-10-22T09:04:48Z",
"title": "Stem Fair",
"message": "The STEM Careers Fair is taking place on 31 October 2018"
},
{
"id": "6F5EE",
"read_state": "unread",
"posted_at": "2018-10-22T09:04:48Z",
"title": "Smile more, worry less with our FREE course",
"message": "Take part in our Online Mindfulness Programme."
},
]
}
}
data.announcements.IFT4S.forEach(item => {
console.log(item.title)
})
or you can do like this,
0 is the index
console.log(data.announcements.IFT4S[0].read_state)
console.log(data.announcements.IFT4S[0].title)
IFT4S is an array, you can access its objects and their values values by calling:
data.announcements.IFT4S[index].title
with index beeing one of 0-2 here since the array contains 3 objects.
For example:
data.announcements.IFT4S[0].title
This is a very basic concept, check out any javascript guide to learn about arrays.

How to loop through array of objects in Node/Express and check if a match exists in MongoDB database?

I am building a web app with the MEAN stack and Yelp API that returns an array of objects, where each object is a local business. I work with this data in the front-end, but before I send a response I want to check if a particular object exists in the MongoDB database and I am struggling with how to do that.
Here is an object that is returned from the API:
[
{
"name": "Arendsnest",
"url": "https://www.yelp.com/biz/arendsnest-amsterdam-2?adjust_creative=ycRBsh7KEkNFq3wJvKoL6Q&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ycRBsh7KEkNFq3wJvKoL6Q",
"snippet_text": "The reigning Lord of Amsterdam beer bars. Popular and seats go fast...come early. Ask for the massive all-Dutch beer list and prepare to have your...",
"image_url": "https://s3-media2.fl.yelpcdn.com/bphoto/FurcfTuqaYBv_q34bGTK5g/ms.jpg"
},
{
"name": "Bar Oldenhof",
"url": "https://www.yelp.com/biz/bar-oldenhof-amsterdam?adjust_creative=ycRBsh7KEkNFq3wJvKoL6Q&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ycRBsh7KEkNFq3wJvKoL6Q",
"snippet_text": "So I'm not much of a drinker. My taste is highly selective and I usually prefer not to drink alcohol altogether. But my husband is the opposite so on a...",
"image_url": "https://s3-media4.fl.yelpcdn.com/bphoto/1k57z7ziIW8MyAWHlXWGdg/ms.jpg"
},
{
"name": "Beer Temple",
"url": "https://www.yelp.com/biz/beer-temple-amsterdam?adjust_creative=ycRBsh7KEkNFq3wJvKoL6Q&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ycRBsh7KEkNFq3wJvKoL6Q",
"snippet_text": "This is a great place to stop in and have some American craft beer. With 30+ taps and a seemingly never ending list of bottle selections, you have many...",
"image_url": "https://s3-media1.fl.yelpcdn.com/bphoto/yxUiYre1Y6ULqMhQ30NPOA/ms.jpg"
},
{
"name": "Tales & Spirits",
"url": "https://www.yelp.com/biz/tales-en-spirits-amsterdam?adjust_creative=ycRBsh7KEkNFq3wJvKoL6Q&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ycRBsh7KEkNFq3wJvKoL6Q",
"snippet_text": "This is exactly what every high-end cocktail bar should strive to have and be.\n\nFriendly staff: From the bartenders to the manager to the waitress. Everyone...",
"image_url": "https://s3-media4.fl.yelpcdn.com/bphoto/IElXytpbY0bpp7ZdjFdGvA/ms.jpg"
}
]
This exists in the MongoDB database:
{
"_id": {
"$oid": "57da26d8dcba0f51172f47b1"
},
"name": "Arendsnest",
"url": "https://www.yelp.com/biz/arendsnest-amsterdam-2?adjust_creative=ycRBsh7KEkNFq3wJvKoL6Q&utm_campaign=yelp_api&utm_medium=api_v2_search&utm_source=ycRBsh7KEkNFq3wJvKoL6Q",
"snippet_text": "The reigning Lord of Amsterdam beer bars. Popular and seats go fast...come early. Ask for the massive all-Dutch beer list and prepare to have your...",
"image_url": "https://s3-media2.fl.yelpcdn.com/bphoto/FurcfTuqaYBv_q34bGTK5g/ms.jpg"
}
How can I write a query in Node to loop through my array using name property and do a check on every object if it exists in the database and return the data?
No need to iterate the array, use the $or operator with a mapped array that has the fields you want to query.
Take the following example where you want to search for a match of two properties:
var yelp = [
{
"name": "Arendsnest",
"url": "url1",
"snippet_text": "foo",
"image_url": "bar.jpg"
},
{
"name": "Bar Oldenhof",
"url": "abc",
"snippet_text": "efg",
"image_url": "ms.jpg"
},
{
"name": "Beer Temple",
"url": "https://www.yelp.com/",
"snippet_text": "test",
"image_url": "ms.jpg"
},
{
"name": "Tales & Spirits",
"url": "https://www.yelp.com/",
"snippet_text": "This is exactly...",
"image_url": "ms.jpg"
}
],
query = yelp.map(function(item){ return { name: item.name, url: item.url }; });
db.collection.find({ "$or": query });
This will create an array that you can use as the $or expression in your find() method, equivalent to :
db.collection.find({
"$or": [
{
"name": "Arendsnest",
"url": "url1"
},
{
"name": "Bar Oldenhof",
"url": "abc"
},
{
"name": "Beer Temple",
"url": "https://www.yelp.com/"
},
{
"name": "Tales & Spirits",
"url": "https://www.yelp.com/"
}
]
})
For querying on single properties, say for instance you want to query on just the name field, better use the $in operator which is better optimised for such:
query = yelp.map(function(item){ return item.name; });
db.collection.find({ "name": { "$in": query } });

Parsing JSON for related key/value within object [duplicate]

This question already has answers here:
Finding matching objects in an array of objects?
(5 answers)
Closed 8 years ago.
Say I have a JSON array containing an bunch of different key/values per each object. I know how to use Javascript to target a specific key/value, but what if I want to search through the entire JSON file to find an item, and then also find a related pair within that same object.
For example, how would I scan the following JSON for "Moby Dick", but then also find the author that is tied to that title?
"store": {
"book": [
{ "category": "reference",
"author": "Nigel Rees",
"title": "Sayings of the Century",
"price": 8.95
},
{ "category": "fiction",
"author": "Evelyn Waugh",
"title": "Sword of Honour",
"price": 12.99
},
{ "category": "fiction",
"author": "Herman Melville",
"title": "Moby Dick",
"isbn": "0-553-21311-3",
"price": 8.99
},
{ "category": "fiction",
"author": "J. R. R. Tolkien",
"title": "The Lord of the Rings",
"isbn": "0-395-19395-8",
"price": 22.99
}
],
}
}
Assuming this is your object:
var store= {
"book": [
{...}, {...}
]
}
Then you can try to filter it like this:
var foundBooks = store.book.filter(function(book) { return book.title ==="Moby Dick"});
As correctly pointed out for #JLRiche foundBooks is an array. In order to access the first match it will be in the same way we do with all arrays:
var book = foundBooks[0];
You'd have to iterate the list, you can create some custom functions, like so:
function findTitle(title) {
for (var i = 0; i < data.store.book.length; i++) {
if (data.store.book[i].title == title) {
return data.store.book[i];
}
}
}
So you can do:
var book = findTitle("Moby Dick"),
author = book.author;
You would loop through your book objects and find where book.title === "Moby Dick" and then take a look at book.author for that particular object.

Categories