使用Elasticsearch NEST C#索引Json文档

时间:2016-06-14 18:28:33

标签: c# json elasticsearch nest

我是Elasticsearch的新手并且想知道如何使用NEST C#将关于json文档的索引和索引创建到Elasticsearch?

{
    "BookName": "Book1",
    "ISBN": "978-3-16-148410-0",
    "chapter" : [
        {
            "chapter_name": "Chapter1",
            "chapter_desc": "Before getting into computer programming, let us first understand computer programs and what they..."
        },
        {
            "chapter_name": "Chapter2",
            "chapter_desc": "Today computer programs are being used in almost every field, household, agriculture, medical, entertainment, defense.."
        },
        {
            "chapter_name": "Chapter3",
            "chapter_desc": "MS Word, MS Excel, Adobe Photoshop, Internet Explorer, Chrome, etc., are..."
        },
        {
            "chapter_name": "Chapter4",
            "chapter_desc": "Computer programs are being used to develop graphics and special effects in movie..."
        }
    ]
}

1 个答案:

答案 0 :(得分:5)

使用NEST创建索引就像

一样简单
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.text.NumberFormat;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;

/**
 * @see https://stackoverflow.com/a/37913520/230513
 * @see https://stackoverflow.com/a/37892395/230513
 */
public class JTableColumnTotalExample {

    public static void main(String[] args) {
        EventQueue.invokeLater(JTableColumnTotalExample::display);
    }

    public static void display() {
        JFrame f = new JFrame("JTable Sorting Example");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        List<Employee> listEmployees = createListEmployees();
        TableModel model = new EmployeeTableModel(listEmployees);
        JTable table = new JTable(model) {
            @Override
            public Dimension getPreferredScrollableViewportSize() {
                return new Dimension(500, getRowCount() * getRowHeight());
            }
        };
        table.getColumnModel().getColumn(3).setCellRenderer(new CurrencyFormatter());
        TableRowSorter sorter = new TableRowSorter<TableModel>(model) {
            @Override
            public int convertRowIndexToModel(int index) {
                int maxRow = super.getViewRowCount();
                if (index >= maxRow) {
                    return index;
                }
                return super.convertRowIndexToModel(index);
            }

            @Override
            public int convertRowIndexToView(int index) {
                int maxRow = super.getModelRowCount();
                if (index > maxRow) {
                    return index;
                }
                return super.convertRowIndexToView(index);
            }

            @Override
            public int getViewRowCount() {
                return super.getViewRowCount() + 1;
            }
        };
        table.setRowSorter(sorter);
        f.add(new JScrollPane(table), BorderLayout.CENTER);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private static List<Employee> createListEmployees() {
        List<Employee> listEmployees = new ArrayList<>();
        listEmployees.add(new Employee("Peter", "Manager", 40000));
        listEmployees.add(new Employee("Paul", "Programmer", 25000));
        listEmployees.add(new Employee("Mary", "Designer", 25000));
        listEmployees.add(new Employee("Donald", "Leader", 30000));
        listEmployees.add(new Employee("Tom", "Designer", 28000));
        listEmployees.add(new Employee("Samantha", "Analyst", 50000));
        listEmployees.add(new Employee("Jerome", "Programmer", 32000));
        listEmployees.add(new Employee("Jonathon", "Developer", 29000));
        listEmployees.add(new Employee("Kevin", "Programmer", 23000));
        listEmployees.add(new Employee("Anthony", "Programmer", 23000));
        listEmployees.add(new Employee("John", "Designer", 33000));
        listEmployees.add(new Employee("David", "Developer", 28000));
        listEmployees.add(new Employee("Harry", "Designer", 31000));
        listEmployees.add(new Employee("Charles", "Programmer", 26000));
        listEmployees.add(new Employee("Joseph", "Manager", 40000));
        return listEmployees;
    }

    private static class EmployeeTableModel extends AbstractTableModel {

        private static final int COLUMN_NUM = 0;
        private static final int COLUMN_NAME = 1;
        private static final int COLUMN_JOB = 2;
        private static final int COLUMN_SALARY = 3;

        private final String[] columnNames = {"No", "Name", "Job", "Salary"};
        private final List<Employee> listEmployees;

        public EmployeeTableModel(List<Employee> listEmployees) {
            this.listEmployees = listEmployees;
            int indexCount = 1;
            for (Employee employee : listEmployees) {
                employee.setIndex(indexCount++);
            }
        }

        @Override
        public int getColumnCount() {
            return columnNames.length;
        }

        @Override
        public int getRowCount() {
            return listEmployees.size();
        }

        @Override
        public String getColumnName(int columnIndex) {
            return columnNames[columnIndex];
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return getValueAt(0, columnIndex).getClass();
        }

        @Override
        public Object getValueAt(int rowIndex, int columnIndex) {
            if (rowIndex == getRowCount()) {
                switch (columnIndex) {
                    case COLUMN_NUM:
                        return 999_999_999;
                    case COLUMN_NAME:
                        return "Total";
                    case COLUMN_JOB:
                        return "Salary";
                    case COLUMN_SALARY:
                        return sum();
                }
            }
            Employee employee = listEmployees.get(rowIndex);
            switch (columnIndex) {
                case COLUMN_NUM:
                    return employee.getIndex();
                case COLUMN_NAME:
                    return employee.getName();
                case COLUMN_JOB:
                    return employee.getJob();
                case COLUMN_SALARY:
                    return employee.getSalary();
                default:
                    throw new IllegalArgumentException("Invalid column index");
            }
        }

        private int sum() {
            int sum = 0;
            for (int r = 0; r < getRowCount(); r++) {
                sum += (int) getValueAt(r, COLUMN_SALARY);
            }
            return sum;
        }
    }

    private static class Employee {

        private int index;
        private String name;
        private String job;
        private int salary;

        public Employee(String name, String job, int salary) {
            this.name = name;
            this.job = job;
            this.salary = salary;
        }

        public int getIndex() {
            return index;
        }

        public void setIndex(int index) {
            this.index = index;
        }

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getJob() {
            return job;
        }

        public void setJob(String job) {
            this.job = job;
        }

        public int getSalary() {
            return salary;
        }

        public void setSalary(int age) {
            this.salary = age;
        }
    }

    private static class CurrencyFormatter extends DefaultTableCellRenderer {

        private NumberFormat numberFormat = NumberFormat.getCurrencyInstance();

        @Override
        public Component getTableCellRendererComponent(JTable jTable, Object value,
            boolean isSelected, boolean hasFocus, int row, int column) {
            Component c = super.getTableCellRendererComponent(jTable, value,
                isSelected, hasFocus, row, column);
            if (c instanceof JLabel && value instanceof Number) {
                JLabel label = (JLabel) c;
                label.setHorizontalAlignment(JLabel.RIGHT);
                Number num = (Number) value;
                String text = numberFormat.format(num);
                label.setText(text);
            }
            return c;
        }
    }
}

这将创建一个索引,其中包含为节点定义的默认分片数和副本数。

将表示为json的文档索引到索引中

var client = new ElasticClient();
client.CreateIndex("index-name");

这里我们使用低级客户端索引json,通过var json = @"{ ""BookName"": ""Book1"", ""ISBN"": ""978-3-16-148410-0"", ""chapter"" : [ { ""chapter_name"": ""Chapter1"", ""chapter_desc"": ""Before getting into computer programming, let us first understand computer programs and what they..."" }, { ""chapter_name"": ""Chapter2"", ""chapter_desc"": ""Today computer programs are being used in almost every field, household, agriculture, medical, entertainment, defense.."" }, { ""chapter_name"": ""Chapter3"", ""chapter_desc"": ""MS Word, MS Excel, Adobe Photoshop, Internet Explorer, Chrome, etc., are..."" }, { ""chapter_name"": ""Chapter4"", ""chapter_desc"": ""Computer programs are being used to develop graphics and special effects in movie..."" } ] }"; var indexResponse = client.LowLevel.Index<string>("index-name", "type-name", json); if (!indexResponse.Success) Console.WriteLine(indexResponse.DebugInformation); 上的.LowLevel属性在NEST中提供。

要搜索索引文档

ElasticClient

这将返回索引的文档。此处// refresh the index so that newly indexed documents are available // for search without waiting for the refresh interval client.Refresh("index-name"); var searchResponse = client.Search<dynamic>(s => s .Index("index-name") .Type("type-name") .Query(q => q .Match(m => m .Query("Photoshop") .Field("chapter.chapter_desc") ) ) ); 中使用的泛型类型参数dynamic表示生成的文档将被反序列化为Json.Net Search<T>()类型。

当我们创建索引时,我们没有为我们的类型JObject指定映射,因此Elasticsearch从json文档的结构推断出映射。 This is dynamic mapping并且在许多情况下都很有用,但是,如果您知道要发送的文档的结构并且不会破坏性地更改,那么您specify a mapping for the type。在这个特定示例中执行此操作的优点是type-name数组将被推断为object type映射,但如果您要搜索单个章节的章节名称和章节描述,那么您可能希望将chapter映射为nested type