Searching on a variable-defined field with ElasticSearch - javascript

Here is the relevant code:
var field = String(querystring.parse(postData).field).toLowerCase();
var qryObj = {
"fields" : view_options,
"query":{
"term" : { field : value}
}
};
The variable 'field' will be a string, like "number", "date", etc. What I want to do is search the index only in the field that is defined in the variable 'field'. This code works if I hardcode the string, like this:
"term" : { "number" : value}
So can someone shed some light on a way to only search a specific field using a predefined variable instead of a string?

You can't use variables as keys in an Object literal. On the left of each :, identifiers themselves become the key's name rather than being evaluated as variables for their values.
console.log({ key: "value" }); // { key: 'value' }
console.log({ "key": "value" }); // { key: 'value' }
You'll have to build the Object first using bracket member operators, then apply it to the query object:
var term = {};
term[field] = value;
var qryObj = {
fields: view_options,
query: {
term: term
}
};
Update:
With ECMAScript 6, Object literals do now support computed keys using bracket notation for the key:
var qryObj = {
fields: view_options,
query: {
term: {
[field]: value
}
}
};

Related

how to transform value string in object to new const js

i need to convert a object with have key value to new object that contain new const named form platform and have name to value in js how to do it?
posters: [
{ platform: facebook; name: ["user test1","user test2"] },
{ platform: instagram; name: ["Ig test1","Ig test2"] },
]
in to
posters: {
facebook: ["user test1","user test2"] ,
instagram: ["Ig test1","Ig test2"] ,
}
Your input array is invalid. There are no strings around your platform values, and you're separating your object properties with a semi-colon rather than a comma. So you would need to fix that in order to proceed.
It looks as if posters is a property within a larger object so this answer will take that into account.
Use reduce on the posters array to iterate over the objects in the array and return an object where the keys are the platform names, and the values the name arrays.
Since it looks like posters is within a larger object we'll rebuild the object using the spread syntax.
const data={posters:[{platform:"facebook",name:["user test1","user test2"]},{platform:"instagram",name:["Ig test1","Ig test2"]}]};
// Create a new object
const updated = {
// Spread out the old object into it
...data,
// And replace the old `posters` property with an
// object using `reduce`. Destructure the `platform`
// and `name` properties from the object, and then
// use them to add a key and a value to the initial
// object (`acc`/accumulator)
posters: data.posters.reduce((acc, obj) => {
const { platform, name } = obj;
acc[platform] = name;
return acc;
}, {})
};
console.log(updated);
Additional documentation
Destructuring assignment
const postersArray = [
{ platform: facebook, name: ["user test1","user test2"] },
{ platform: instagram, name: ["Ig test1","Ig test2"] }
]
const postersObject = postersArray.reduce((previous, current) => {
return {
…previous,
[current.platform]: current.name
}
},{})

Alternative to eval for converting a string to an object

I have a function that is using eval to convert a string with an expression to an object based on the parameter.
let indexType = ["Mac", "User", "Line", "Mask", "Ip", "Location"]
const filterIndex = (item) => {
filteredIndexSearch = []
eval(`search${item}`).forEach((e) => filteredIndexSearch.push(searchData[e.key]))
}
filterIndex(indexType[searchTotal.indexOf(Math.max(...searchTotal))])
searchData is an array that returns values based on the user input.
searchTotal is an array with the length of each search{item} array.
The filterIndex function takes the highest value from the searchData array and corresponds it to the indexType array, then use eval to convert the string to an object to pass the value to the filteredIndexSearch array.
What would be a better alternative to eval?
EDIT
To add more information on what this does:
searchData = [
[
{
key: 1,
data: "0123456789101"
},
{
key: 1,
data: "John Smith"
}
],
[
{
key: 2,
data: "0123456789102"
},
{
key: 2,
data: "Jane Smith"
},
]
]
const search = (data, key, container) => {
if (!data) data = "";
if (data.toLowerCase().includes(string)) {
container = container[container.length] = {
key: key,
data: data
}
}
}
const returnSearch = () => {
for (let i = 0; i < searchData.length; i++) {
search(searchData[i][0].data, searchData[i][0].key, searchMac)
search(searchData[i][1].data, searchData[i][1].key, searchUser)
}
}
returnSearch()
The data is incomplete, but hopefully conveys what I'm trying to do.
search will take the user input, and store the information in the corresponding array. If I input "Jo", it will return the searchUser array with only the "John Smith" value and all the other values with the same key. Inputting "102" returns the searchMac with the "0123456789102" value and all other values with the same key.
At the end of the day. I just want to convert search${parameter} to an object without using eval.
Move your global arrays into an object.
Somewhere it appears that you're defining the arrays, something like:
searchMac = [...];
searchUser = [...];
...
Instead of defining them as individual arrays, I'd define them as properties in an object:
searchIndices.Mac = [...];
searchIndices.User = [...];
...
Then, instead of using eval, your can replace your eval().forEach with searchIndices[item].forEach.
If the order of your search isn't important, your can instead loop through the keys of searchIndices:
Object.keys(searchIndices).forEach(item => {
searchIndices[item].forEach(...);
});
This ensures that if you ever add or drop an entry in searchIndices, you won't miss it or accidentally error out on an undefined search index.
Any time you have a situation with variables named x0, x1 etc, that should be a red flag to tell you you should be using an array instead. Variable names should never be semantically meaningful - that is code should never rely on the name of a variable to determine how the code behaves. Convert search0 etc into an array of search terms. Then use:
const filterIndex = (item) => search[item].map(i => searchData[i.key]);
filteredIndexSearch = filterIndex(indexType[searchTotal.indexOf(Math.max(...searchTotal))]);
(simplifying your code). Note that in your code, filteredIndexSearch is modified inside the arrow function. Better to have it return the result as above.

convert response from api to object with specific format

I have this response from api
columns: Array(4)
0: "Id"
1: "Title"
2: "Description"
3: "IsActive"
and I need to convert it to this format, so there will "fields" and under the fields it list down the values from the api response and on each value there will be type which I need to determine also if it's Id or IsActive then it will be number. I'm only allow to follow this specific object format and also I need to support IE browser
fields: {
Id: { type: "number" },
Title: { type: "string" },
Description: { type: "string" },
IsActive: { type: "number" }
}
You need to include the additional information about which types are numeric somewhere. This solution stores those in an array, passes this array into a function, and gets back a function which takes an array of columns and returns an object of field definitions.
const makeFields = (numericTypes) => (columns) => columns.reduce(
(a, s) => ({...a, [s]: {type: numericTypes.includes(s) ? 'numeric' : 'string'}}),
{}
)
const numericTypes = ['Id', "IsActive"]
const columns = ["Id", "Title", "Description", "IsActive"]
console.log(makeFields(numericTypes)(columns))
You can save that intermediate function with something like const makeMyFields = makeFields(numericTypes) and then later using it as makeMyFields(columns)
Update
Here is another version that should work in IE (untested):
const makeFields = function(numericTypes) {
return function(columns) {
return columns.reduce(function(a, s) {
a[s] = {type: numericTypes.includes(s) ? 'numeric' : 'string'}
return a
}, {})
}
}
Update 2
You were having problems running this code. I'm guessing that you supplied the parameters incorrectly. Note that this version required you to pass the list of numeric values to get back a function you would then call with the list of columns to get back an object of the types. That is, you had to call it like this:
// makeFields (numericTypes) (columns)
// ^ ^ ^------ call that new function with column names
// | `---- call with list of numeric types, returns a new function
// `-- function name
It's easy enough to change the function so that you can supply all the parameters in one go. But there is an advantage to that formulation. You can call the outer function with the numeric types and get back a reusable function. That inner function can then be applied to any set of columns you choose. It could be passed, say, to map, so that if you had multiple sets of columns, you could simply write multipleColumns.map(makeFields(numericTypes)).
But if you want to change it, the new version might look like this:
const makeFields = function(numericTypes, columns) {
return columns.reduce(function(a, s) {
a[s] = {type: numericTypes.includes(s) ? 'numeric' : 'string'}
return a
}, {})
}
const numericTypes = ['Id', "IsActive"]
const columns = ["Id", "Title", "Description", "IsActive"]
console.log(makeFields(numericTypes, columns))

How to put your object data from a form under specific properties

I have a JSON getting submitted by a form e.g. below.
Var obj1 = {
input1: 'name',
input2: 'surname',
input3: 'email'
}
Now the back-end database has been configured to accept values like this.
FormData: [{
"Key": "input1",
"Value": "Test"
}]
So each value needs to be under key and value, how do I put my input1 and input2 etc under a key and value property for every value in JavaScript? I'm using React but plain JavaScript will do.
var obj1 = {
input1: 'name',
input2: 'surname',
input3: 'email'
}
console.log(Object.keys(obj1).map(Key => ({
Key,
Value: obj1[Key]
})))
Get keys of the object obj1, and then map over it to produce an array of objects.
Try this :
let FormData = Object.keys(obj1).map(key => {
return {"Key" : key, "Value" : obj1[key]}
})

Javascript dotted object keys to object

How do you convert a dotted keys into a javascript object and retain it's value?
So I got this kind of response from an API and I need to parse it by key: value.
{
"property": "personal_info.address.city",
"description": "Missing field"
},
{
"property": "personal_info.address.country",
"description": "Missing field"
},
So I achieved this:
{
'personal_info.address.city': 'Missing field',
'personal_info.address.country': 'Missing field'
}
// by using this code (lodash)
_.mapValues(_.keyBy(obj, 'property'), function(o) {
return o.description;
})
however, i need it to be like this:
{
personal_info: {
address: {
city: 'Missing field',
country: 'Missing field',
}
}
}
I somehow searched in stackoverflow how to convert a dot notation string into an object here:
Convert string with dot notation to JSON
but I'm stuck since I'm changing the key itself.
EDIT:
Changed test city and test country to reflect the description field (sorry)
You could use _.set from lodash.
Sets the value at path of object. If a portion of path doesn't exist, it's created. Arrays are created for missing index properties while objects are created for all other missing properties. Use _.setWith to customize path creation.
var array = [{ property: "personal_info.address.city", description: "Missing field" }, { property: "personal_info.address.country", description: "Missing field" }],
object = array.reduce((o, { property, description }) => _.set(o, property, description), {});
console.log(object);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>
You could use forEach() loop and inside reduce() method to get result like this.
const data = [{"property": "personal_info.address.city","description": "Missing field"},{"property": "personal_info.address.country","description": "Missing field"}]
const result = {}
data.forEach(function(o) {
o.property.split('.').reduce(function(r, e, i, arr) {
return r[e] = (r[e] || (arr[i + 1] ? {} : o.description))
}, result)
})
console.log(result)

Categories

Resources