Elasticsearch脚本查询按字段值获取参数

时间:2016-12-18 15:31:45

标签: elasticsearch elasticsearch-painless

我正在尝试使用脚本查询过滤结果。 我可以使用硬编码字段值访问参数值,如下所示:

"script": "doc['price'].value * params.1000 > 4000",
      "params": {"1000": "1.75"}

但是如果我尝试使用doc获取字段值,则没有过滤,我可以看到所有结果。

    "script": "doc['price'].value * params.doc['rate'] > 4000",
      "params": {"1000": "1.75"}

有没有动态获取参数值的解决方案?

编辑:

Field'rate'就是ID。它是整数,但它不是我需要的价值。我们的想法是通过参数每次传递不同的值,而不是经常更新字段'rate'。希望这是更好的解释......

示例:

"script": "doc['price'].value * params.doc['rate'] > 4000",
  "params": {
              "1000": "1.75",
              "1001": "3.75",
              "1002": "5"
            }

if 
'price' == 10 &&
'rate' == 1002
result should be: 10 * 5 > 4000  

if 
'price' == 10 &&
'rate' == 1001
result should be: 10 * 3.75 > 4000

if 
'price' == 7 &&
'rate' == 1000
result should be: 7 * 1.75 > 4000   

2 个答案:

答案 0 :(得分:0)

我假设integer "script": "(doc['price'].value * doc['rate'].value) > 4000", <--replace params with doc "params": {"1000": "1.75"} ,如果是这样,脚本应该不是这样的。如果我已正确理解您的过滤,如果没有,请纠正我:

var express = require('express');
var router = express.Router();
var Conversation = require('../models/conversation');
var Promise = require('promise');

// Get Homepage
router.get('/', function(req, res){
	res.render('index');
});


var messages = [];
router.get('/inbox', function(req, res){
	var promise = new Promise(function (resolve, reject) {
		req.user.conversations.forEach(function(id){
			Conversation.getConversationById(id, function(err, conv){
				if (conv){
					messages.push(conv);
					if(messages.length == req.user.conversations.length){
						resolve(messages);
						messages = [];
					}
				} else {
					console.log(err);
				}
			});
		});
	}).then(function(object){
		res.render('inbox', {convers: object});
	}).catch(function(err){
		console.log(err);
	});
});

// Add new messages to messagesArray -> mesgArray to display them
var mesgArray = [];
var userIdFor = "";
router.post('/messages', function(req, res){
	var convId = req.body.conversationId;
	userIdFor = req.user.id;
	var promise = new Promise(function(resolve, reject){
		Conversation.getConversationById(convId, function(err, conver){
			if (err){
				console.log(err);
			} else {
				conver.messages.forEach(function(messa){
					mesgArray.push({msg: messa.msg, owner: messa.msgOwner, ownerName: messa.msgOwnerName});
					if(mesgArray.length == conver.messages.length){
						resolve(mesgArray);
					}
				});
			}
		});
	}).then(function(object){
		res.send({allMessages: object, userId: userIdFor});
		mesgArray = [];
		userIdFor = "";
	}).catch(function(err){
		console.log(err);
	});
});

// Save posted message to existent conversation
router.post('/saveMsg', function(req, res){
	var conversationId = req.body.conversationId;
	var messageToSave = req.body.message;
	console.log(messageToSave);
	console.log(conversationId);
	Conversation.getConversationById(conversationId, function(err, conversation){
		if (err){
			console.log(err);
		} else {
			Conversation.getConversationById(conversationId, function(err, conversation){
				if(err){
					console.log(err)
				} else {
					conversation.messages.push({
						msg: messageToSave,
						msgOwner: req.user.id,
						msgOwnerName: req.user.firstName
					});
					conversation.save(function(err){
						if(err){
							console.log(err);
						}
					})
				}
			});
		}
	});
});

module.exports = router;

答案 1 :(得分:0)

你可以尝试这样的事情:

"script": {
    "lang": "painless",
    "inline": "doc['price'].value * params.get(doc['rate'].toString()) > 4000",
    "params": {
        "[1000]": 1.75,
        "[1001]": 3.75,
        "[1002]": 5
    }
}

为什么参数需要方括号我不知道,但是使用带有Debug.explain(doc['rate'].toString())的脚本表明转换为字符串的费率字段就是这样(也许你可以使用rate的关键字字段,在这种情况下,我认为参数可以与字段值具有完全相同的名称):

"error": {
    "caused_by": {
        "reason": null,
        "type": "painless_explain_error"
    },
    "class": "java.lang.String",
    "lang": "painless",
    ...
    "script": "Debug.explain(doc['rate'].toString())",
    ...
    "to_string": "[1000]",
},
...

我使用params.get是因为params是一个HashMap(再次使用Debug.explain(params)找到)。参数值也不是字符串。